diff options
Diffstat (limited to '')
-rw-r--r-- | C/Sha1.c | 125 |
1 files changed, 34 insertions, 91 deletions
@@ -1,18 +1,14 @@ | |||
1 | /* Sha1.c -- SHA-1 Hash | 1 | /* Sha1.c -- SHA-1 Hash |
2 | 2024-03-01 : Igor Pavlov : Public domain | 2 | : Igor Pavlov : Public domain |
3 | This code is based on public domain code of Steve Reid from Wei Dai's Crypto++ library. */ | 3 | This 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 | ||
226 | void Sha1_InitState(CSha1 *p) | 222 | void 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 | ||
236 | void Sha1_Init(CSha1 *p) | 232 | void 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 | ||
332 | void Sha1_Final(CSha1 *p, Byte *digest) | 324 | void 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 | ||
385 | void Sha1_PrepareBlock(const CSha1 *p, Byte *block, unsigned size) | 353 | void 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 | ||
421 | void Sha1Prepare(void) | 389 | void 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 |