aboutsummaryrefslogtreecommitdiff
path: root/C/Sha512.c
diff options
context:
space:
mode:
Diffstat (limited to 'C/Sha512.c')
-rw-r--r--C/Sha512.c167
1 files changed, 130 insertions, 37 deletions
diff --git a/C/Sha512.c b/C/Sha512.c
index 04827d6..f0787fd 100644
--- a/C/Sha512.c
+++ b/C/Sha512.c
@@ -439,26 +439,78 @@ void Sha512_Final(CSha512 *p, Byte *digest, unsigned digestSize)
439 439
440 440
441 441
442// #define Z7_SHA512_PROBE_DEBUG // for debug
442 443
443#if defined(_WIN32) && defined(Z7_COMPILER_SHA512_SUPPORTED) \ 444#if defined(Z7_SHA512_PROBE_DEBUG) || defined(Z7_COMPILER_SHA512_SUPPORTED)
444 && defined(MY_CPU_ARM64) // we can disable this check to debug in x64
445 445
446#if 1 // 0 for debug 446#if defined(Z7_SHA512_PROBE_DEBUG) \
447 || defined(_WIN32) && defined(MY_CPU_ARM64)
448#ifndef Z7_SHA512_USE_PROBE
449#define Z7_SHA512_USE_PROBE
450#endif
451#endif
447 452
448#include "7zWindows.h" 453#ifdef Z7_SHA512_USE_PROBE
449// #include <stdio.h> 454
450#if 0 && defined(MY_CPU_X86_OR_AMD64) 455#ifdef Z7_SHA512_PROBE_DEBUG
451#include <intrin.h> // for debug : for __ud2() 456#include <stdio.h>
457#define PRF(x) x
458#else
459#define PRF(x)
452#endif 460#endif
453 461
454BoolInt CPU_IsSupported_SHA512(void) 462#if 0 || !defined(_MSC_VER) // 1 || : for debug LONGJMP mode
463// MINGW doesn't support __try. So we use signal() / longjmp().
464// Note: signal() / longjmp() probably is not thread-safe.
465// So we must call Sha512Prepare() from main thread at program start.
466#ifndef Z7_SHA512_USE_LONGJMP
467#define Z7_SHA512_USE_LONGJMP
468#endif
469#endif
470
471#ifdef Z7_SHA512_USE_LONGJMP
472#include <signal.h>
473#include <setjmp.h>
474static jmp_buf g_Sha512_jmp_buf;
475// static int g_Sha512_Unsupported;
476
477#if defined(__GNUC__) && (__GNUC__ >= 8) \
478 || defined(__clang__) && (__clang_major__ >= 3)
479 __attribute__((noreturn))
480#endif
481static void Z7_CDECL Sha512_signal_Handler(int v)
455{ 482{
483 PRF(printf("======== Sha512_signal_Handler = %x\n", (unsigned)v);)
484 // g_Sha512_Unsupported = 1;
485 longjmp(g_Sha512_jmp_buf, 1);
486}
487#endif // Z7_SHA512_USE_LONGJMP
488
489
490#if defined(_WIN32)
491#include "7zWindows.h"
492#endif
493
456#if defined(MY_CPU_ARM64) 494#if defined(MY_CPU_ARM64)
495// #define Z7_SHA512_USE_SIMPLIFIED_PROBE // for debug
496#endif
497
498#ifdef Z7_SHA512_USE_SIMPLIFIED_PROBE
499#include <arm_neon.h>
500#if defined(__clang__)
501 __attribute__((__target__("sha3")))
502#elif !defined(_MSC_VER)
503 __attribute__((__target__("arch=armv8.2-a+sha3")))
504#endif
505#endif
506static BoolInt CPU_IsSupported_SHA512_Probe(void)
507{
508 PRF(printf("\n== CPU_IsSupported_SHA512_Probe\n");)
509#if defined(_WIN32) && defined(MY_CPU_ARM64)
457 // we have no SHA512 flag for IsProcessorFeaturePresent() still. 510 // we have no SHA512 flag for IsProcessorFeaturePresent() still.
458 if (!CPU_IsSupported_CRYPTO()) 511 if (!CPU_IsSupported_CRYPTO())
459 return False; 512 return False;
460#endif 513 PRF(printf("==== Registry check\n");)
461 // printf("\nCPU_IsSupported_SHA512\n");
462 { 514 {
463 // we can't read ID_AA64ISAR0_EL1 register from application. 515 // we can't read ID_AA64ISAR0_EL1 register from application.
464 // but ID_AA64ISAR0_EL1 register is mapped to "CP 4030" registry value. 516 // but ID_AA64ISAR0_EL1 register is mapped to "CP 4030" registry value.
@@ -486,6 +538,7 @@ BoolInt CPU_IsSupported_SHA512(void)
486 // 2 : SHA256 and SHA512 implemented 538 // 2 : SHA256 and SHA512 implemented
487 } 539 }
488 } 540 }
541#endif // defined(_WIN32) && defined(MY_CPU_ARM64)
489 542
490 543
491#if 1 // 0 for debug to disable SHA512 PROBE code 544#if 1 // 0 for debug to disable SHA512 PROBE code
@@ -509,59 +562,97 @@ Does this PROBE code work in native Windows-arm64 (with/without sha512 hw instru
509Are there any ways to fix the problems with arm64-wine and x64-SDE cases? 562Are there any ways to fix the problems with arm64-wine and x64-SDE cases?
510*/ 563*/
511 564
512 // printf("\n========== CPU_IsSupported_SHA512 PROBE ========\n"); 565 PRF(printf("==== CPU_IsSupported_SHA512 PROBE\n");)
513 { 566 {
567 BoolInt isSupported = False;
568#ifdef Z7_SHA512_USE_LONGJMP
569 void (Z7_CDECL *signal_prev)(int);
570 /*
571 if (g_Sha512_Unsupported)
572 {
573 PRF(printf("==== g_Sha512_Unsupported\n");)
574 return False;
575 }
576 */
577 printf("====== signal(SIGILL)\n");
578 signal_prev = signal(SIGILL, Sha512_signal_Handler);
579 if (signal_prev == SIG_ERR)
580 {
581 PRF(printf("====== signal fail\n");)
582 return False;
583 }
584 // PRF(printf("==== signal_prev = %p\n", (void *)signal_prev);)
585 // docs: Before the specified function is executed,
586 // the value of func is set to SIG_DFL.
587 // So we can exit if (setjmp(g_Sha512_jmp_buf) != 0).
588 PRF(printf("====== setjmp\n");)
589 if (!setjmp(g_Sha512_jmp_buf))
590#else // Z7_SHA512_USE_LONGJMP
591
592#ifdef _MSC_VER
514#ifdef __clang_major__ 593#ifdef __clang_major__
515 #pragma GCC diagnostic ignored "-Wlanguage-extension-token" 594 #pragma GCC diagnostic ignored "-Wlanguage-extension-token"
516#endif 595#endif
517 __try 596 __try
597#endif
598#endif // Z7_SHA512_USE_LONGJMP
599
518 { 600 {
519#if 0 // 1 : for debug (reduced version to detect sha512) 601#if defined(Z7_COMPILER_SHA512_SUPPORTED)
602#ifdef Z7_SHA512_USE_SIMPLIFIED_PROBE
603 // simplified sha512 check for arm64:
520 const uint64x2_t a = vdupq_n_u64(1); 604 const uint64x2_t a = vdupq_n_u64(1);
521 const uint64x2_t b = vsha512hq_u64(a, a, a); 605 const uint64x2_t b = vsha512hq_u64(a, a, a);
606 PRF(printf("======== vsha512hq_u64 probe\n");)
522 if ((UInt32)vgetq_lane_u64(b, 0) == 0x11800002) 607 if ((UInt32)vgetq_lane_u64(b, 0) == 0x11800002)
523 return True;
524#else 608#else
525 MY_ALIGN(16) 609 MY_ALIGN(16)
526 UInt64 temp[SHA512_NUM_DIGEST_WORDS + SHA512_NUM_BLOCK_WORDS]; 610 UInt64 temp[SHA512_NUM_DIGEST_WORDS + SHA512_NUM_BLOCK_WORDS];
527 memset(temp, 0x5a, sizeof(temp)); 611 memset(temp, 0x5a, sizeof(temp));
528#if 0 && defined(MY_CPU_X86_OR_AMD64) 612 PRF(printf("======== Sha512_UpdateBlocks_HW\n");)
529 __ud2(); // for debug : that exception is not problem for SDE
530#endif
531#if 1
532 Sha512_UpdateBlocks_HW(temp, 613 Sha512_UpdateBlocks_HW(temp,
533 (const Byte *)(const void *)(temp + SHA512_NUM_DIGEST_WORDS), 1); 614 (const Byte *)(const void *)(temp + SHA512_NUM_DIGEST_WORDS), 1);
534 // printf("\n==== t = %x\n", (UInt32)temp[0]); 615 // PRF(printf("======== t = %x\n", (UInt32)temp[0]);)
535 if ((UInt32)temp[0] == 0xa33cfdf7) 616 if ((UInt32)temp[0] == 0xa33cfdf7)
617#endif
536 { 618 {
537 // printf("\n=== PROBE SHA512: SHA512 supported\n"); 619 PRF(printf("======== PROBE SHA512: SHA512 is supported\n");)
538 return True; 620 isSupported = True;
539 } 621 }
622#else // Z7_COMPILER_SHA512_SUPPORTED
623 // for debug : we generate bad instrction or raise exception.
624 // __except() doesn't catch raise() calls.
625#ifdef Z7_SHA512_USE_LONGJMP
626 PRF(printf("====== raise(SIGILL)\n");)
627 raise(SIGILL);
628#else
629#if defined(_MSC_VER) && defined(MY_CPU_X86)
630 __asm ud2
540#endif 631#endif
541#endif 632#endif // Z7_SHA512_USE_LONGJMP
633#endif // Z7_COMPILER_SHA512_SUPPORTED
542 } 634 }
635
636#ifdef Z7_SHA512_USE_LONGJMP
637 PRF(printf("====== restore signal SIGILL\n");)
638 signal(SIGILL, signal_prev);
639#elif _MSC_VER
543 __except (EXCEPTION_EXECUTE_HANDLER) 640 __except (EXCEPTION_EXECUTE_HANDLER)
544 { 641 {
545 // printf("\n==== CPU_IsSupported_SHA512 EXCEPTION_EXECUTE_HANDLER\n"); 642 PRF(printf("==== CPU_IsSupported_SHA512 __except(EXCEPTION_EXECUTE_HANDLER)\n");)
546 } 643 }
644#endif
645 PRF(printf("== return (sha512 supported) = %d\n", isSupported);)
646 return isSupported;
547 } 647 }
548 return False;
549#else 648#else
550 // without SHA512 PROBE code 649 // without SHA512 PROBE code
551 return True; 650 return True;
552#endif 651#endif
553
554} 652}
555 653
556#else 654#endif // Z7_SHA512_USE_PROBE
557 655#endif // defined(Z7_SHA512_PROBE_DEBUG) || defined(Z7_COMPILER_SHA512_SUPPORTED)
558BoolInt CPU_IsSupported_SHA512(void)
559{
560 return False;
561}
562
563#endif
564#endif // WIN32 arm64
565 656
566 657
567void Sha512Prepare(void) 658void Sha512Prepare(void)
@@ -570,10 +661,10 @@ void Sha512Prepare(void)
570 SHA512_FUNC_UPDATE_BLOCKS f, f_hw; 661 SHA512_FUNC_UPDATE_BLOCKS f, f_hw;
571 f = Sha512_UpdateBlocks; 662 f = Sha512_UpdateBlocks;
572 f_hw = NULL; 663 f_hw = NULL;
573#ifdef MY_CPU_X86_OR_AMD64 664#ifdef Z7_SHA512_USE_PROBE
574 if (CPU_IsSupported_SHA512() 665 if (CPU_IsSupported_SHA512_Probe())
575 && CPU_IsSupported_AVX2() 666#elif defined(MY_CPU_X86_OR_AMD64)
576 ) 667 if (CPU_IsSupported_SHA512() && CPU_IsSupported_AVX2())
577#else 668#else
578 if (CPU_IsSupported_SHA512()) 669 if (CPU_IsSupported_SHA512())
579#endif 670#endif
@@ -583,6 +674,8 @@ void Sha512Prepare(void)
583 } 674 }
584 g_SHA512_FUNC_UPDATE_BLOCKS = f; 675 g_SHA512_FUNC_UPDATE_BLOCKS = f;
585 g_SHA512_FUNC_UPDATE_BLOCKS_HW = f_hw; 676 g_SHA512_FUNC_UPDATE_BLOCKS_HW = f_hw;
677#elif defined(Z7_SHA512_PROBE_DEBUG)
678 CPU_IsSupported_SHA512_Probe(); // for debug
586#endif 679#endif
587} 680}
588 681