rlm@1
|
1 // Crypto/Sha1.cpp
|
rlm@1
|
2 // This file is based on public domain
|
rlm@1
|
3 // Steve Reid and Wei Dai's code from Crypto++
|
rlm@1
|
4
|
rlm@1
|
5 #include "StdAfx.h"
|
rlm@1
|
6
|
rlm@1
|
7 #include "Sha1.h"
|
rlm@1
|
8 extern "C"
|
rlm@1
|
9 {
|
rlm@1
|
10 #include "../../../C/RotateDefs.h"
|
rlm@1
|
11 }
|
rlm@1
|
12
|
rlm@1
|
13 namespace NCrypto {
|
rlm@1
|
14 namespace NSha1 {
|
rlm@1
|
15
|
rlm@1
|
16 // define it for speed optimization
|
rlm@1
|
17 // #define _SHA1_UNROLL
|
rlm@1
|
18
|
rlm@1
|
19 static const unsigned kNumW =
|
rlm@1
|
20 #ifdef _SHA1_UNROLL
|
rlm@1
|
21 16;
|
rlm@1
|
22 #else
|
rlm@1
|
23 80;
|
rlm@1
|
24 #endif
|
rlm@1
|
25
|
rlm@1
|
26
|
rlm@1
|
27 #define w0(i) (W[(i)] = data[(i)])
|
rlm@1
|
28
|
rlm@1
|
29 #ifdef _SHA1_UNROLL
|
rlm@1
|
30 #define w1(i) (W[(i)&15] = rotlFixed(W[((i)-3)&15] ^ W[((i)-8)&15] ^ W[((i)-14)&15] ^ W[((i)-16)&15], 1))
|
rlm@1
|
31 #else
|
rlm@1
|
32 #define w1(i) (W[(i)] = rotlFixed(W[(i)-3] ^ W[(i)-8] ^ W[(i)-14] ^ W[(i)-16], 1))
|
rlm@1
|
33 #endif
|
rlm@1
|
34
|
rlm@1
|
35 #define f1(x,y,z) (z^(x&(y^z)))
|
rlm@1
|
36 #define f2(x,y,z) (x^y^z)
|
rlm@1
|
37 #define f3(x,y,z) ((x&y)|(z&(x|y)))
|
rlm@1
|
38 #define f4(x,y,z) (x^y^z)
|
rlm@1
|
39
|
rlm@1
|
40 #define RK1(a,b,c,d,e,i, f, w, k) e += f(b,c,d) + w(i) + k + rotlFixed(a,5); b = rotlFixed(b,30);
|
rlm@1
|
41
|
rlm@1
|
42 #define R0(a,b,c,d,e,i) RK1(a,b,c,d,e,i, f1, w0, 0x5A827999)
|
rlm@1
|
43 #define R1(a,b,c,d,e,i) RK1(a,b,c,d,e,i, f1, w1, 0x5A827999)
|
rlm@1
|
44 #define R2(a,b,c,d,e,i) RK1(a,b,c,d,e,i, f2, w1, 0x6ED9EBA1)
|
rlm@1
|
45 #define R3(a,b,c,d,e,i) RK1(a,b,c,d,e,i, f3, w1, 0x8F1BBCDC)
|
rlm@1
|
46 #define R4(a,b,c,d,e,i) RK1(a,b,c,d,e,i, f4, w1, 0xCA62C1D6)
|
rlm@1
|
47
|
rlm@1
|
48 #define RX_1_4(rx1, rx4, i) rx1(a,b,c,d,e,i); rx4(e,a,b,c,d,i+1); rx4(d,e,a,b,c,i+2); rx4(c,d,e,a,b,i+3); rx4(b,c,d,e,a,i+4);
|
rlm@1
|
49 #define RX_5(rx, i) RX_1_4(rx, rx, i);
|
rlm@1
|
50
|
rlm@1
|
51 void CContextBase::Init()
|
rlm@1
|
52 {
|
rlm@1
|
53 _state[0] = 0x67452301;
|
rlm@1
|
54 _state[1] = 0xEFCDAB89;
|
rlm@1
|
55 _state[2] = 0x98BADCFE;
|
rlm@1
|
56 _state[3] = 0x10325476;
|
rlm@1
|
57 _state[4] = 0xC3D2E1F0;
|
rlm@1
|
58 _count = 0;
|
rlm@1
|
59 }
|
rlm@1
|
60
|
rlm@1
|
61 void CContextBase::GetBlockDigest(UInt32 *data, UInt32 *destDigest, bool returnRes)
|
rlm@1
|
62 {
|
rlm@1
|
63 UInt32 a, b, c, d, e;
|
rlm@1
|
64 UInt32 W[kNumW];
|
rlm@1
|
65
|
rlm@1
|
66 a = _state[0];
|
rlm@1
|
67 b = _state[1];
|
rlm@1
|
68 c = _state[2];
|
rlm@1
|
69 d = _state[3];
|
rlm@1
|
70 e = _state[4];
|
rlm@1
|
71 #ifdef _SHA1_UNROLL
|
rlm@1
|
72 RX_5(R0, 0); RX_5(R0, 5); RX_5(R0, 10);
|
rlm@1
|
73 #else
|
rlm@1
|
74 int i;
|
rlm@1
|
75 for (i = 0; i < 15; i += 5) { RX_5(R0, i); }
|
rlm@1
|
76 #endif
|
rlm@1
|
77
|
rlm@1
|
78 RX_1_4(R0, R1, 15);
|
rlm@1
|
79
|
rlm@1
|
80
|
rlm@1
|
81 #ifdef _SHA1_UNROLL
|
rlm@1
|
82 RX_5(R2, 20); RX_5(R2, 25); RX_5(R2, 30); RX_5(R2, 35);
|
rlm@1
|
83 RX_5(R3, 40); RX_5(R3, 45); RX_5(R3, 50); RX_5(R3, 55);
|
rlm@1
|
84 RX_5(R4, 60); RX_5(R4, 65); RX_5(R4, 70); RX_5(R4, 75);
|
rlm@1
|
85 #else
|
rlm@1
|
86 i = 20;
|
rlm@1
|
87 for (; i < 40; i += 5) { RX_5(R2, i); }
|
rlm@1
|
88 for (; i < 60; i += 5) { RX_5(R3, i); }
|
rlm@1
|
89 for (; i < 80; i += 5) { RX_5(R4, i); }
|
rlm@1
|
90 #endif
|
rlm@1
|
91
|
rlm@1
|
92 destDigest[0] = _state[0] + a;
|
rlm@1
|
93 destDigest[1] = _state[1] + b;
|
rlm@1
|
94 destDigest[2] = _state[2] + c;
|
rlm@1
|
95 destDigest[3] = _state[3] + d;
|
rlm@1
|
96 destDigest[4] = _state[4] + e;
|
rlm@1
|
97
|
rlm@1
|
98 if (returnRes)
|
rlm@1
|
99 for (int i = 0 ; i < 16; i++)
|
rlm@1
|
100 data[i] = W[kNumW - 16 + i];
|
rlm@1
|
101
|
rlm@1
|
102 // Wipe variables
|
rlm@1
|
103 // a = b = c = d = e = 0;
|
rlm@1
|
104 }
|
rlm@1
|
105
|
rlm@1
|
106 void CContextBase::PrepareBlock(UInt32 *block, unsigned size) const
|
rlm@1
|
107 {
|
rlm@1
|
108 unsigned curBufferPos = size & 0xF;
|
rlm@1
|
109 block[curBufferPos++] = 0x80000000;
|
rlm@1
|
110 while (curBufferPos != (16 - 2))
|
rlm@1
|
111 block[curBufferPos++] = 0;
|
rlm@1
|
112 const UInt64 lenInBits = (_count << 9) + ((UInt64)size << 5);
|
rlm@1
|
113 block[curBufferPos++] = (UInt32)(lenInBits >> 32);
|
rlm@1
|
114 block[curBufferPos++] = (UInt32)(lenInBits);
|
rlm@1
|
115 }
|
rlm@1
|
116
|
rlm@1
|
117 void CContext::Update(Byte *data, size_t size, bool rar350Mode)
|
rlm@1
|
118 {
|
rlm@1
|
119 bool returnRes = false;
|
rlm@1
|
120 unsigned curBufferPos = _count2;
|
rlm@1
|
121 while (size-- > 0)
|
rlm@1
|
122 {
|
rlm@1
|
123 int pos = (int)(curBufferPos & 3);
|
rlm@1
|
124 if (pos == 0)
|
rlm@1
|
125 _buffer[curBufferPos >> 2] = 0;
|
rlm@1
|
126 _buffer[curBufferPos >> 2] |= ((UInt32)*data++) << (8 * (3 - pos));
|
rlm@1
|
127 if (++curBufferPos == kBlockSize)
|
rlm@1
|
128 {
|
rlm@1
|
129 curBufferPos = 0;
|
rlm@1
|
130 CContextBase::UpdateBlock(_buffer, returnRes);
|
rlm@1
|
131 if (returnRes)
|
rlm@1
|
132 for (int i = 0; i < kBlockSizeInWords; i++)
|
rlm@1
|
133 {
|
rlm@1
|
134 UInt32 d = _buffer[i];
|
rlm@1
|
135 data[i * 4 + 0 - kBlockSize] = (Byte)(d);
|
rlm@1
|
136 data[i * 4 + 1 - kBlockSize] = (Byte)(d >> 8);
|
rlm@1
|
137 data[i * 4 + 2 - kBlockSize] = (Byte)(d >> 16);
|
rlm@1
|
138 data[i * 4 + 3 - kBlockSize] = (Byte)(d >> 24);
|
rlm@1
|
139 }
|
rlm@1
|
140 returnRes = rar350Mode;
|
rlm@1
|
141 }
|
rlm@1
|
142 }
|
rlm@1
|
143 _count2 = curBufferPos;
|
rlm@1
|
144 }
|
rlm@1
|
145
|
rlm@1
|
146 void CContext::Final(Byte *digest)
|
rlm@1
|
147 {
|
rlm@1
|
148 const UInt64 lenInBits = (_count << 9) + ((UInt64)_count2 << 3);
|
rlm@1
|
149 unsigned curBufferPos = _count2;
|
rlm@1
|
150 int pos = (int)(curBufferPos & 3);
|
rlm@1
|
151 curBufferPos >>= 2;
|
rlm@1
|
152 if (pos == 0)
|
rlm@1
|
153 _buffer[curBufferPos] = 0;
|
rlm@1
|
154 _buffer[curBufferPos++] |= ((UInt32)0x80) << (8 * (3 - pos));
|
rlm@1
|
155
|
rlm@1
|
156 while (curBufferPos != (16 - 2))
|
rlm@1
|
157 {
|
rlm@1
|
158 curBufferPos &= 0xF;
|
rlm@1
|
159 if (curBufferPos == 0)
|
rlm@1
|
160 UpdateBlock();
|
rlm@1
|
161 _buffer[curBufferPos++] = 0;
|
rlm@1
|
162 }
|
rlm@1
|
163 _buffer[curBufferPos++] = (UInt32)(lenInBits >> 32);
|
rlm@1
|
164 _buffer[curBufferPos++] = (UInt32)(lenInBits);
|
rlm@1
|
165 UpdateBlock();
|
rlm@1
|
166
|
rlm@1
|
167 int i;
|
rlm@1
|
168 for (i = 0; i < kDigestSizeInWords; i++)
|
rlm@1
|
169 {
|
rlm@1
|
170 UInt32 state = _state[i] & 0xFFFFFFFF;
|
rlm@1
|
171 *digest++ = (Byte)(state >> 24);
|
rlm@1
|
172 *digest++ = (Byte)(state >> 16);
|
rlm@1
|
173 *digest++ = (Byte)(state >> 8);
|
rlm@1
|
174 *digest++ = (Byte)(state);
|
rlm@1
|
175 }
|
rlm@1
|
176 Init();
|
rlm@1
|
177 }
|
rlm@1
|
178
|
rlm@1
|
179 ///////////////////////////
|
rlm@1
|
180 // Words version
|
rlm@1
|
181
|
rlm@1
|
182 void CContext32::Update(const UInt32 *data, size_t size)
|
rlm@1
|
183 {
|
rlm@1
|
184 while (size-- > 0)
|
rlm@1
|
185 {
|
rlm@1
|
186 _buffer[_count2++] = *data++;
|
rlm@1
|
187 if (_count2 == kBlockSizeInWords)
|
rlm@1
|
188 {
|
rlm@1
|
189 _count2 = 0;
|
rlm@1
|
190 UpdateBlock();
|
rlm@1
|
191 }
|
rlm@1
|
192 }
|
rlm@1
|
193 }
|
rlm@1
|
194
|
rlm@1
|
195 void CContext32::Final(UInt32 *digest)
|
rlm@1
|
196 {
|
rlm@1
|
197 const UInt64 lenInBits = (_count << 9) + ((UInt64)_count2 << 5);
|
rlm@1
|
198 unsigned curBufferPos = _count2;
|
rlm@1
|
199 _buffer[curBufferPos++] = 0x80000000;
|
rlm@1
|
200 while (curBufferPos != (16 - 2))
|
rlm@1
|
201 {
|
rlm@1
|
202 curBufferPos &= 0xF;
|
rlm@1
|
203 if (curBufferPos == 0)
|
rlm@1
|
204 UpdateBlock();
|
rlm@1
|
205 _buffer[curBufferPos++] = 0;
|
rlm@1
|
206 }
|
rlm@1
|
207 _buffer[curBufferPos++] = (UInt32)(lenInBits >> 32);
|
rlm@1
|
208 _buffer[curBufferPos++] = (UInt32)(lenInBits);
|
rlm@1
|
209 GetBlockDigest(_buffer, digest);
|
rlm@1
|
210 Init();
|
rlm@1
|
211 }
|
rlm@1
|
212
|
rlm@1
|
213 }}
|