xref: /aosp_15_r20/external/lzma/C/Sha1.c (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1 /* Sha1.c -- SHA-1 Hash
2 : Igor Pavlov : Public domain
3 This code is based on public domain code of Steve Reid from Wei Dai's Crypto++ library. */
4 
5 #include "Precomp.h"
6 
7 #include <string.h>
8 
9 #include "Sha1.h"
10 #include "RotateDefs.h"
11 #include "CpuArch.h"
12 
13 #ifdef MY_CPU_X86_OR_AMD64
14   #if   defined(Z7_LLVM_CLANG_VERSION)  && (Z7_LLVM_CLANG_VERSION  >= 30800) \
15      || defined(Z7_APPLE_CLANG_VERSION) && (Z7_APPLE_CLANG_VERSION >= 50100) \
16      || defined(Z7_GCC_VERSION)         && (Z7_GCC_VERSION         >= 40900) \
17      || defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1600) \
18      || defined(_MSC_VER) && (_MSC_VER >= 1200)
19       #define Z7_COMPILER_SHA1_SUPPORTED
20   #endif
21 #elif defined(MY_CPU_ARM_OR_ARM64) && defined(MY_CPU_LE) \
22    && (!defined(Z7_MSC_VER_ORIGINAL) || (_MSC_VER >= 1929) && (_MSC_FULL_VER >= 192930037))
23   #if   defined(__ARM_FEATURE_SHA2) \
24      || defined(__ARM_FEATURE_CRYPTO)
25     #define Z7_COMPILER_SHA1_SUPPORTED
26   #else
27     #if  defined(MY_CPU_ARM64) \
28       || defined(__ARM_ARCH) && (__ARM_ARCH >= 4) \
29       || defined(Z7_MSC_VER_ORIGINAL)
30     #if  defined(__ARM_FP) && \
31           (   defined(Z7_CLANG_VERSION) && (Z7_CLANG_VERSION >= 30800) \
32            || defined(__GNUC__) && (__GNUC__ >= 6) \
33           ) \
34       || defined(Z7_MSC_VER_ORIGINAL) && (_MSC_VER >= 1910)
35     #if  defined(MY_CPU_ARM64) \
36       || !defined(Z7_CLANG_VERSION) \
37       || defined(__ARM_NEON) && \
38           (Z7_CLANG_VERSION < 170000 || \
39            Z7_CLANG_VERSION > 170001)
40       #define Z7_COMPILER_SHA1_SUPPORTED
41     #endif
42     #endif
43     #endif
44   #endif
45 #endif
46 
47 void Z7_FASTCALL Sha1_UpdateBlocks(UInt32 state[5], const Byte *data, size_t numBlocks);
48 
49 #ifdef Z7_COMPILER_SHA1_SUPPORTED
50   void Z7_FASTCALL Sha1_UpdateBlocks_HW(UInt32 state[5], const Byte *data, size_t numBlocks);
51 
52   static SHA1_FUNC_UPDATE_BLOCKS g_SHA1_FUNC_UPDATE_BLOCKS = Sha1_UpdateBlocks;
53   static SHA1_FUNC_UPDATE_BLOCKS g_SHA1_FUNC_UPDATE_BLOCKS_HW;
54 
55   #define SHA1_UPDATE_BLOCKS(p) p->v.vars.func_UpdateBlocks
56 #else
57   #define SHA1_UPDATE_BLOCKS(p) Sha1_UpdateBlocks
58 #endif
59 
60 
Sha1_SetFunction(CSha1 * p,unsigned algo)61 BoolInt Sha1_SetFunction(CSha1 *p, unsigned algo)
62 {
63   SHA1_FUNC_UPDATE_BLOCKS func = Sha1_UpdateBlocks;
64 
65   #ifdef Z7_COMPILER_SHA1_SUPPORTED
66     if (algo != SHA1_ALGO_SW)
67     {
68       if (algo == SHA1_ALGO_DEFAULT)
69         func = g_SHA1_FUNC_UPDATE_BLOCKS;
70       else
71       {
72         if (algo != SHA1_ALGO_HW)
73           return False;
74         func = g_SHA1_FUNC_UPDATE_BLOCKS_HW;
75         if (!func)
76           return False;
77       }
78     }
79   #else
80     if (algo > 1)
81       return False;
82   #endif
83 
84   p->v.vars.func_UpdateBlocks = func;
85   return True;
86 }
87 
88 
89 /* define it for speed optimization */
90 // #define Z7_SHA1_UNROLL
91 
92 // allowed unroll steps: (1, 2, 4, 5, 20)
93 
94 #undef Z7_SHA1_BIG_W
95 #ifdef Z7_SHA1_UNROLL
96   #define STEP_PRE  20
97   #define STEP_MAIN 20
98 #else
99   #define Z7_SHA1_BIG_W
100   #define STEP_PRE  5
101   #define STEP_MAIN 5
102 #endif
103 
104 
105 #ifdef Z7_SHA1_BIG_W
106   #define kNumW 80
107   #define w(i) W[i]
108 #else
109   #define kNumW 16
110   #define w(i) W[(i)&15]
111 #endif
112 
113 #define w0(i) (W[i] = GetBe32(data + (size_t)(i) * 4))
114 #define w1(i) (w(i) = rotlFixed(w((size_t)(i)-3) ^ w((size_t)(i)-8) ^ w((size_t)(i)-14) ^ w((size_t)(i)-16), 1))
115 
116 #define f0(x,y,z)  ( 0x5a827999 + (z^(x&(y^z))) )
117 #define f1(x,y,z)  ( 0x6ed9eba1 + (x^y^z) )
118 #define f2(x,y,z)  ( 0x8f1bbcdc + ((x&y)|(z&(x|y))) )
119 #define f3(x,y,z)  ( 0xca62c1d6 + (x^y^z) )
120 
121 /*
122 #define T1(fx, ww) \
123     tmp = e + fx(b,c,d) + ww + rotlFixed(a, 5); \
124     e = d; \
125     d = c; \
126     c = rotlFixed(b, 30); \
127     b = a; \
128     a = tmp; \
129 */
130 
131 #define T5(a,b,c,d,e, fx, ww) \
132     e += fx(b,c,d) + ww + rotlFixed(a, 5); \
133     b = rotlFixed(b, 30); \
134 
135 
136 /*
137 #define R1(i, fx, wx) \
138     T1 ( fx, wx(i)); \
139 
140 #define R2(i, fx, wx) \
141     R1 ( (i)    , fx, wx); \
142     R1 ( (i) + 1, fx, wx); \
143 
144 #define R4(i, fx, wx) \
145     R2 ( (i)    , fx, wx); \
146     R2 ( (i) + 2, fx, wx); \
147 */
148 
149 #define M5(i, fx, wx0, wx1) \
150     T5 ( a,b,c,d,e, fx, wx0((i)  ) ) \
151     T5 ( e,a,b,c,d, fx, wx1((i)+1) ) \
152     T5 ( d,e,a,b,c, fx, wx1((i)+2) ) \
153     T5 ( c,d,e,a,b, fx, wx1((i)+3) ) \
154     T5 ( b,c,d,e,a, fx, wx1((i)+4) ) \
155 
156 #define R5(i, fx, wx) \
157     M5 ( i, fx, wx, wx) \
158 
159 
160 #if STEP_PRE > 5
161 
162   #define R20_START \
163     R5 (  0, f0, w0) \
164     R5 (  5, f0, w0) \
165     R5 ( 10, f0, w0) \
166     M5 ( 15, f0, w0, w1) \
167 
168   #elif STEP_PRE == 5
169 
170   #define R20_START \
171     { size_t i; for (i = 0; i < 15; i += STEP_PRE) \
172       { R5(i, f0, w0) } } \
173     M5 ( 15, f0, w0, w1) \
174 
175 #else
176 
177   #if STEP_PRE == 1
178     #define R_PRE R1
179   #elif STEP_PRE == 2
180     #define R_PRE R2
181   #elif STEP_PRE == 4
182     #define R_PRE R4
183   #endif
184 
185   #define R20_START \
186     { size_t i; for (i = 0; i < 16; i += STEP_PRE) \
187       { R_PRE(i, f0, w0) } } \
188     R4 ( 16, f0, w1) \
189 
190 #endif
191 
192 
193 
194 #if STEP_MAIN > 5
195 
196   #define R20(ii, fx) \
197     R5 ( (ii)     , fx, w1) \
198     R5 ( (ii) + 5 , fx, w1) \
199     R5 ( (ii) + 10, fx, w1) \
200     R5 ( (ii) + 15, fx, w1) \
201 
202 #else
203 
204   #if STEP_MAIN == 1
205     #define R_MAIN R1
206   #elif STEP_MAIN == 2
207     #define R_MAIN R2
208   #elif STEP_MAIN == 4
209     #define R_MAIN R4
210   #elif STEP_MAIN == 5
211     #define R_MAIN R5
212   #endif
213 
214   #define R20(ii, fx)  \
215     { size_t i; for (i = (ii); i < (ii) + 20; i += STEP_MAIN) \
216       { R_MAIN(i, fx, w1) } } \
217 
218 #endif
219 
220 
221 
Sha1_InitState(CSha1 * p)222 void Sha1_InitState(CSha1 *p)
223 {
224   p->v.vars.count = 0;
225   p->state[0] = 0x67452301;
226   p->state[1] = 0xEFCDAB89;
227   p->state[2] = 0x98BADCFE;
228   p->state[3] = 0x10325476;
229   p->state[4] = 0xC3D2E1F0;
230 }
231 
Sha1_Init(CSha1 * p)232 void Sha1_Init(CSha1 *p)
233 {
234   p->v.vars.func_UpdateBlocks =
235   #ifdef Z7_COMPILER_SHA1_SUPPORTED
236       g_SHA1_FUNC_UPDATE_BLOCKS;
237   #else
238       NULL;
239   #endif
240   Sha1_InitState(p);
241 }
242 
243 
244 Z7_NO_INLINE
Sha1_UpdateBlocks(UInt32 state[5],const Byte * data,size_t numBlocks)245 void Z7_FASTCALL Sha1_UpdateBlocks(UInt32 state[5], const Byte *data, size_t numBlocks)
246 {
247   UInt32 a, b, c, d, e;
248   UInt32 W[kNumW];
249 
250   if (numBlocks == 0)
251     return;
252 
253   a = state[0];
254   b = state[1];
255   c = state[2];
256   d = state[3];
257   e = state[4];
258 
259   do
260   {
261   #if STEP_PRE < 5 || STEP_MAIN < 5
262   UInt32 tmp;
263   #endif
264 
265   R20_START
266   R20(20, f1)
267   R20(40, f2)
268   R20(60, f3)
269 
270   a += state[0];
271   b += state[1];
272   c += state[2];
273   d += state[3];
274   e += state[4];
275 
276   state[0] = a;
277   state[1] = b;
278   state[2] = c;
279   state[3] = d;
280   state[4] = e;
281 
282   data += SHA1_BLOCK_SIZE;
283   }
284   while (--numBlocks);
285 }
286 
287 
288 #define Sha1_UpdateBlock(p) SHA1_UPDATE_BLOCKS(p)(p->state, p->buffer, 1)
289 
Sha1_Update(CSha1 * p,const Byte * data,size_t size)290 void Sha1_Update(CSha1 *p, const Byte *data, size_t size)
291 {
292   if (size == 0)
293     return;
294   {
295     const unsigned pos = (unsigned)p->v.vars.count & (SHA1_BLOCK_SIZE - 1);
296     const unsigned num = SHA1_BLOCK_SIZE - pos;
297     p->v.vars.count += size;
298     if (num > size)
299     {
300       memcpy(p->buffer + pos, data, size);
301       return;
302     }
303     if (pos != 0)
304     {
305       size -= num;
306       memcpy(p->buffer + pos, data, num);
307       data += num;
308       Sha1_UpdateBlock(p);
309     }
310   }
311   {
312     const size_t numBlocks = size >> 6;
313     // if (numBlocks)
314     SHA1_UPDATE_BLOCKS(p)(p->state, data, numBlocks);
315     size &= SHA1_BLOCK_SIZE - 1;
316     if (size == 0)
317       return;
318     data += (numBlocks << 6);
319     memcpy(p->buffer, data, size);
320   }
321 }
322 
323 
Sha1_Final(CSha1 * p,Byte * digest)324 void Sha1_Final(CSha1 *p, Byte *digest)
325 {
326   unsigned pos = (unsigned)p->v.vars.count & (SHA1_BLOCK_SIZE - 1);
327   p->buffer[pos++] = 0x80;
328   if (pos > (SHA1_BLOCK_SIZE - 4 * 2))
329   {
330     while (pos != SHA1_BLOCK_SIZE) { p->buffer[pos++] = 0; }
331     // memset(&p->buf.buffer[pos], 0, SHA1_BLOCK_SIZE - pos);
332     Sha1_UpdateBlock(p);
333     pos = 0;
334   }
335   memset(&p->buffer[pos], 0, (SHA1_BLOCK_SIZE - 4 * 2) - pos);
336   {
337     const UInt64 numBits = p->v.vars.count << 3;
338     SetBe32(p->buffer + SHA1_BLOCK_SIZE - 4 * 2, (UInt32)(numBits >> 32))
339     SetBe32(p->buffer + SHA1_BLOCK_SIZE - 4 * 1, (UInt32)(numBits))
340   }
341   Sha1_UpdateBlock(p);
342 
343   SetBe32(digest,      p->state[0])
344   SetBe32(digest + 4,  p->state[1])
345   SetBe32(digest + 8,  p->state[2])
346   SetBe32(digest + 12, p->state[3])
347   SetBe32(digest + 16, p->state[4])
348 
349   Sha1_InitState(p);
350 }
351 
352 
Sha1_PrepareBlock(const CSha1 * p,Byte * block,unsigned size)353 void Sha1_PrepareBlock(const CSha1 *p, Byte *block, unsigned size)
354 {
355   const UInt64 numBits = (p->v.vars.count + size) << 3;
356   SetBe32(&((UInt32 *)(void *)block)[SHA1_NUM_BLOCK_WORDS - 2], (UInt32)(numBits >> 32))
357   SetBe32(&((UInt32 *)(void *)block)[SHA1_NUM_BLOCK_WORDS - 1], (UInt32)(numBits))
358   // SetBe32((UInt32 *)(block + size), 0x80000000);
359   SetUi32((UInt32 *)(void *)(block + size), 0x80)
360   size += 4;
361   while (size != (SHA1_NUM_BLOCK_WORDS - 2) * 4)
362   {
363     *((UInt32 *)(void *)(block + size)) = 0;
364     size += 4;
365   }
366 }
367 
Sha1_GetBlockDigest(const CSha1 * p,const Byte * data,Byte * destDigest)368 void Sha1_GetBlockDigest(const CSha1 *p, const Byte *data, Byte *destDigest)
369 {
370   MY_ALIGN (16)
371   UInt32 st[SHA1_NUM_DIGEST_WORDS];
372 
373   st[0] = p->state[0];
374   st[1] = p->state[1];
375   st[2] = p->state[2];
376   st[3] = p->state[3];
377   st[4] = p->state[4];
378 
379   SHA1_UPDATE_BLOCKS(p)(st, data, 1);
380 
381   SetBe32(destDigest + 0    , st[0])
382   SetBe32(destDigest + 1 * 4, st[1])
383   SetBe32(destDigest + 2 * 4, st[2])
384   SetBe32(destDigest + 3 * 4, st[3])
385   SetBe32(destDigest + 4 * 4, st[4])
386 }
387 
388 
Sha1Prepare(void)389 void Sha1Prepare(void)
390 {
391 #ifdef Z7_COMPILER_SHA1_SUPPORTED
392   SHA1_FUNC_UPDATE_BLOCKS f, f_hw;
393   f = Sha1_UpdateBlocks;
394   f_hw = NULL;
395 #ifdef MY_CPU_X86_OR_AMD64
396   if (CPU_IsSupported_SHA()
397       && CPU_IsSupported_SSSE3()
398       )
399 #else
400   if (CPU_IsSupported_SHA1())
401 #endif
402   {
403     // printf("\n========== HW SHA1 ======== \n");
404 #if 1 && defined(MY_CPU_ARM_OR_ARM64) && defined(Z7_MSC_VER_ORIGINAL) && (_MSC_FULL_VER < 192930037)
405     /* there was bug in MSVC compiler for ARM64 -O2 before version VS2019 16.10 (19.29.30037).
406        It generated incorrect SHA-1 code. */
407       #pragma message("== SHA1 code can work incorrectly with this compiler")
408       #error Stop_Compiling_MSC_Compiler_BUG_SHA1
409 #endif
410       {
411         f = f_hw = Sha1_UpdateBlocks_HW;
412       }
413   }
414   g_SHA1_FUNC_UPDATE_BLOCKS    = f;
415   g_SHA1_FUNC_UPDATE_BLOCKS_HW = f_hw;
416 #endif
417 }
418 
419 #undef kNumW
420 #undef w
421 #undef w0
422 #undef w1
423 #undef f0
424 #undef f1
425 #undef f2
426 #undef f3
427 #undef T1
428 #undef T5
429 #undef M5
430 #undef R1
431 #undef R2
432 #undef R4
433 #undef R5
434 #undef R20_START
435 #undef R_PRE
436 #undef R_MAIN
437 #undef STEP_PRE
438 #undef STEP_MAIN
439 #undef Z7_SHA1_BIG_W
440 #undef Z7_SHA1_UNROLL
441 #undef Z7_COMPILER_SHA1_SUPPORTED
442