aboutsummaryrefslogtreecommitdiff
path: root/C/Sha1.c
diff options
context:
space:
mode:
authorIgor Pavlov <87184205+ip7z@users.noreply.github.com>2024-11-29 00:00:00 +0000
committerIgor Pavlov <87184205+ip7z@users.noreply.github.com>2024-11-30 15:27:15 +0500
commite5431fa6f5505e385c6f9367260717e9c47dc2ee (patch)
tree4cd2c2c3b225b48c8e7053432c41d7b6b6a3d5f8 /C/Sha1.c
parente008ce3976c087bfd21344af8f00a23cf69d4174 (diff)
download7zip-e5431fa6f5505e385c6f9367260717e9c47dc2ee.tar.gz
7zip-e5431fa6f5505e385c6f9367260717e9c47dc2ee.tar.bz2
7zip-e5431fa6f5505e385c6f9367260717e9c47dc2ee.zip
Diffstat (limited to 'C/Sha1.c')
-rw-r--r--C/Sha1.c125
1 files changed, 34 insertions, 91 deletions
diff --git a/C/Sha1.c b/C/Sha1.c
index 4c92892..4ca21d7 100644
--- a/C/Sha1.c
+++ b/C/Sha1.c
@@ -1,18 +1,14 @@
1/* Sha1.c -- SHA-1 Hash 1/* Sha1.c -- SHA-1 Hash
22024-03-01 : Igor Pavlov : Public domain 2: Igor Pavlov : Public domain
3This code is based on public domain code of Steve Reid from Wei Dai's Crypto++ library. */ 3This code is based on public domain code of Steve Reid from Wei Dai's Crypto++ library. */
4 4
5#include "Precomp.h" 5#include "Precomp.h"
6 6
7#include <string.h> 7#include <string.h>
8 8
9#include "CpuArch.h"
10#include "RotateDefs.h"
11#include "Sha1.h" 9#include "Sha1.h"
12 10#include "RotateDefs.h"
13#if defined(_MSC_VER) && (_MSC_VER < 1900) 11#include "CpuArch.h"
14// #define USE_MY_MM
15#endif
16 12
17#ifdef MY_CPU_X86_OR_AMD64 13#ifdef MY_CPU_X86_OR_AMD64
18 #if defined(Z7_LLVM_CLANG_VERSION) && (Z7_LLVM_CLANG_VERSION >= 30800) \ 14 #if defined(Z7_LLVM_CLANG_VERSION) && (Z7_LLVM_CLANG_VERSION >= 30800) \
@@ -56,7 +52,7 @@ void Z7_FASTCALL Sha1_UpdateBlocks(UInt32 state[5], const Byte *data, size_t num
56 static SHA1_FUNC_UPDATE_BLOCKS g_SHA1_FUNC_UPDATE_BLOCKS = Sha1_UpdateBlocks; 52 static SHA1_FUNC_UPDATE_BLOCKS g_SHA1_FUNC_UPDATE_BLOCKS = Sha1_UpdateBlocks;
57 static SHA1_FUNC_UPDATE_BLOCKS g_SHA1_FUNC_UPDATE_BLOCKS_HW; 53 static SHA1_FUNC_UPDATE_BLOCKS g_SHA1_FUNC_UPDATE_BLOCKS_HW;
58 54
59 #define SHA1_UPDATE_BLOCKS(p) p->func_UpdateBlocks 55 #define SHA1_UPDATE_BLOCKS(p) p->v.vars.func_UpdateBlocks
60#else 56#else
61 #define SHA1_UPDATE_BLOCKS(p) Sha1_UpdateBlocks 57 #define SHA1_UPDATE_BLOCKS(p) Sha1_UpdateBlocks
62#endif 58#endif
@@ -85,7 +81,7 @@ BoolInt Sha1_SetFunction(CSha1 *p, unsigned algo)
85 return False; 81 return False;
86 #endif 82 #endif
87 83
88 p->func_UpdateBlocks = func; 84 p->v.vars.func_UpdateBlocks = func;
89 return True; 85 return True;
90} 86}
91 87
@@ -225,7 +221,7 @@ BoolInt Sha1_SetFunction(CSha1 *p, unsigned algo)
225 221
226void Sha1_InitState(CSha1 *p) 222void Sha1_InitState(CSha1 *p)
227{ 223{
228 p->count = 0; 224 p->v.vars.count = 0;
229 p->state[0] = 0x67452301; 225 p->state[0] = 0x67452301;
230 p->state[1] = 0xEFCDAB89; 226 p->state[1] = 0xEFCDAB89;
231 p->state[2] = 0x98BADCFE; 227 p->state[2] = 0x98BADCFE;
@@ -235,7 +231,7 @@ void Sha1_InitState(CSha1 *p)
235 231
236void Sha1_Init(CSha1 *p) 232void Sha1_Init(CSha1 *p)
237{ 233{
238 p->func_UpdateBlocks = 234 p->v.vars.func_UpdateBlocks =
239 #ifdef Z7_COMPILER_SHA1_SUPPORTED 235 #ifdef Z7_COMPILER_SHA1_SUPPORTED
240 g_SHA1_FUNC_UPDATE_BLOCKS; 236 g_SHA1_FUNC_UPDATE_BLOCKS;
241 #else 237 #else
@@ -250,7 +246,7 @@ void Z7_FASTCALL Sha1_UpdateBlocks(UInt32 state[5], const Byte *data, size_t num
250{ 246{
251 UInt32 a, b, c, d, e; 247 UInt32 a, b, c, d, e;
252 UInt32 W[kNumW]; 248 UInt32 W[kNumW];
253 // if (numBlocks != 0x1264378347) return; 249
254 if (numBlocks == 0) 250 if (numBlocks == 0)
255 return; 251 return;
256 252
@@ -283,7 +279,7 @@ void Z7_FASTCALL Sha1_UpdateBlocks(UInt32 state[5], const Byte *data, size_t num
283 state[3] = d; 279 state[3] = d;
284 state[4] = e; 280 state[4] = e;
285 281
286 data += 64; 282 data += SHA1_BLOCK_SIZE;
287 } 283 }
288 while (--numBlocks); 284 while (--numBlocks);
289} 285}
@@ -295,20 +291,15 @@ void Sha1_Update(CSha1 *p, const Byte *data, size_t size)
295{ 291{
296 if (size == 0) 292 if (size == 0)
297 return; 293 return;
298
299 { 294 {
300 unsigned pos = (unsigned)p->count & 0x3F; 295 const unsigned pos = (unsigned)p->v.vars.count & (SHA1_BLOCK_SIZE - 1);
301 unsigned num; 296 const unsigned num = SHA1_BLOCK_SIZE - pos;
302 297 p->v.vars.count += size;
303 p->count += size;
304
305 num = 64 - pos;
306 if (num > size) 298 if (num > size)
307 { 299 {
308 memcpy(p->buffer + pos, data, size); 300 memcpy(p->buffer + pos, data, size);
309 return; 301 return;
310 } 302 }
311
312 if (pos != 0) 303 if (pos != 0)
313 { 304 {
314 size -= num; 305 size -= num;
@@ -318,9 +309,10 @@ void Sha1_Update(CSha1 *p, const Byte *data, size_t size)
318 } 309 }
319 } 310 }
320 { 311 {
321 size_t numBlocks = size >> 6; 312 const size_t numBlocks = size >> 6;
313 // if (numBlocks)
322 SHA1_UPDATE_BLOCKS(p)(p->state, data, numBlocks); 314 SHA1_UPDATE_BLOCKS(p)(p->state, data, numBlocks);
323 size &= 0x3F; 315 size &= SHA1_BLOCK_SIZE - 1;
324 if (size == 0) 316 if (size == 0)
325 return; 317 return;
326 data += (numBlocks << 6); 318 data += (numBlocks << 6);
@@ -331,42 +323,21 @@ void Sha1_Update(CSha1 *p, const Byte *data, size_t size)
331 323
332void Sha1_Final(CSha1 *p, Byte *digest) 324void Sha1_Final(CSha1 *p, Byte *digest)
333{ 325{
334 unsigned pos = (unsigned)p->count & 0x3F; 326 unsigned pos = (unsigned)p->v.vars.count & (SHA1_BLOCK_SIZE - 1);
335
336
337 p->buffer[pos++] = 0x80; 327 p->buffer[pos++] = 0x80;
338 328 if (pos > (SHA1_BLOCK_SIZE - 4 * 2))
339 if (pos > (64 - 8))
340 { 329 {
341 while (pos != 64) { p->buffer[pos++] = 0; } 330 while (pos != SHA1_BLOCK_SIZE) { p->buffer[pos++] = 0; }
342 // memset(&p->buf.buffer[pos], 0, 64 - pos); 331 // memset(&p->buf.buffer[pos], 0, SHA1_BLOCK_SIZE - pos);
343 Sha1_UpdateBlock(p); 332 Sha1_UpdateBlock(p);
344 pos = 0; 333 pos = 0;
345 } 334 }
346 335 memset(&p->buffer[pos], 0, (SHA1_BLOCK_SIZE - 4 * 2) - pos);
347 /*
348 if (pos & 3)
349 {
350 p->buffer[pos] = 0;
351 p->buffer[pos + 1] = 0;
352 p->buffer[pos + 2] = 0;
353 pos += 3;
354 pos &= ~3;
355 }
356 {
357 for (; pos < 64 - 8; pos += 4)
358 *(UInt32 *)(&p->buffer[pos]) = 0;
359 }
360 */
361
362 memset(&p->buffer[pos], 0, (64 - 8) - pos);
363
364 { 336 {
365 const UInt64 numBits = (p->count << 3); 337 const UInt64 numBits = p->v.vars.count << 3;
366 SetBe32(p->buffer + 64 - 8, (UInt32)(numBits >> 32)) 338 SetBe32(p->buffer + SHA1_BLOCK_SIZE - 4 * 2, (UInt32)(numBits >> 32))
367 SetBe32(p->buffer + 64 - 4, (UInt32)(numBits)) 339 SetBe32(p->buffer + SHA1_BLOCK_SIZE - 4 * 1, (UInt32)(numBits))
368 } 340 }
369
370 Sha1_UpdateBlock(p); 341 Sha1_UpdateBlock(p);
371 342
372 SetBe32(digest, p->state[0]) 343 SetBe32(digest, p->state[0])
@@ -375,16 +346,13 @@ void Sha1_Final(CSha1 *p, Byte *digest)
375 SetBe32(digest + 12, p->state[3]) 346 SetBe32(digest + 12, p->state[3])
376 SetBe32(digest + 16, p->state[4]) 347 SetBe32(digest + 16, p->state[4])
377 348
378
379
380
381 Sha1_InitState(p); 349 Sha1_InitState(p);
382} 350}
383 351
384 352
385void Sha1_PrepareBlock(const CSha1 *p, Byte *block, unsigned size) 353void Sha1_PrepareBlock(const CSha1 *p, Byte *block, unsigned size)
386{ 354{
387 const UInt64 numBits = (p->count + size) << 3; 355 const UInt64 numBits = (p->v.vars.count + size) << 3;
388 SetBe32(&((UInt32 *)(void *)block)[SHA1_NUM_BLOCK_WORDS - 2], (UInt32)(numBits >> 32)) 356 SetBe32(&((UInt32 *)(void *)block)[SHA1_NUM_BLOCK_WORDS - 2], (UInt32)(numBits >> 32))
389 SetBe32(&((UInt32 *)(void *)block)[SHA1_NUM_BLOCK_WORDS - 1], (UInt32)(numBits)) 357 SetBe32(&((UInt32 *)(void *)block)[SHA1_NUM_BLOCK_WORDS - 1], (UInt32)(numBits))
390 // SetBe32((UInt32 *)(block + size), 0x80000000); 358 // SetBe32((UInt32 *)(block + size), 0x80000000);
@@ -420,57 +388,32 @@ void Sha1_GetBlockDigest(const CSha1 *p, const Byte *data, Byte *destDigest)
420 388
421void Sha1Prepare(void) 389void Sha1Prepare(void)
422{ 390{
423 #ifdef Z7_COMPILER_SHA1_SUPPORTED 391#ifdef Z7_COMPILER_SHA1_SUPPORTED
424 SHA1_FUNC_UPDATE_BLOCKS f, f_hw; 392 SHA1_FUNC_UPDATE_BLOCKS f, f_hw;
425 f = Sha1_UpdateBlocks; 393 f = Sha1_UpdateBlocks;
426 f_hw = NULL; 394 f_hw = NULL;
427 #ifdef MY_CPU_X86_OR_AMD64 395#ifdef MY_CPU_X86_OR_AMD64
428 #ifndef USE_MY_MM
429 if (CPU_IsSupported_SHA() 396 if (CPU_IsSupported_SHA()
430 && CPU_IsSupported_SSSE3() 397 && CPU_IsSupported_SSSE3()
431 // && CPU_IsSupported_SSE41()
432 ) 398 )
433 #endif 399#else
434 #else
435 if (CPU_IsSupported_SHA1()) 400 if (CPU_IsSupported_SHA1())
436 #endif 401#endif
437 { 402 {
438 // printf("\n========== HW SHA1 ======== \n"); 403 // printf("\n========== HW SHA1 ======== \n");
439 #if 0 && defined(MY_CPU_ARM_OR_ARM64) && defined(_MSC_VER) 404#if 1 && defined(MY_CPU_ARM_OR_ARM64) && defined(Z7_MSC_VER_ORIGINAL) && (_MSC_FULL_VER < 192930037)
440 /* there was bug in MSVC compiler for ARM64 -O2 before version VS2019 16.10 (19.29.30037). 405 /* there was bug in MSVC compiler for ARM64 -O2 before version VS2019 16.10 (19.29.30037).
441 It generated incorrect SHA-1 code. 406 It generated incorrect SHA-1 code. */
442 21.03 : we test sha1-hardware code at runtime initialization */ 407 #pragma message("== SHA1 code can work incorrectly with this compiler")
443 408 #error Stop_Compiling_MSC_Compiler_BUG_SHA1
444 #pragma message("== SHA1 code: MSC compiler : failure-check code was inserted") 409#endif
445
446 UInt32 state[5] = { 0, 1, 2, 3, 4 } ;
447 Byte data[64];
448 unsigned i;
449 for (i = 0; i < sizeof(data); i += 2)
450 {
451 data[i ] = (Byte)(i);
452 data[i + 1] = (Byte)(i + 1);
453 }
454
455 Sha1_UpdateBlocks_HW(state, data, sizeof(data) / 64);
456
457 if ( state[0] != 0x9acd7297
458 || state[1] != 0x4624d898
459 || state[2] != 0x0bf079f0
460 || state[3] != 0x031e61b3
461 || state[4] != 0x8323fe20)
462 {
463 // printf("\n========== SHA-1 hardware version failure ======== \n");
464 }
465 else
466 #endif
467 { 410 {
468 f = f_hw = Sha1_UpdateBlocks_HW; 411 f = f_hw = Sha1_UpdateBlocks_HW;
469 } 412 }
470 } 413 }
471 g_SHA1_FUNC_UPDATE_BLOCKS = f; 414 g_SHA1_FUNC_UPDATE_BLOCKS = f;
472 g_SHA1_FUNC_UPDATE_BLOCKS_HW = f_hw; 415 g_SHA1_FUNC_UPDATE_BLOCKS_HW = f_hw;
473 #endif 416#endif
474} 417}
475 418
476#undef kNumW 419#undef kNumW