6 #ifndef EXCEPTION_EXECUTE_HANDLER 7 # define EXCEPTION_EXECUTE_HANDLER 1 10 #ifndef CRYPTOPP_IMPORTS 16 #ifndef CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY 23 #ifndef CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY 27 #endif // Not CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY 29 #ifdef CRYPTOPP_CPUID_AVAILABLE 31 #if _MSC_VER >= 1400 && CRYPTOPP_BOOL_X64 35 __cpuid((
int *)output, input);
41 #ifndef CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY 44 static jmp_buf s_jmpNoCPUID;
45 static void SigIllHandlerCPUID(
int)
47 longjmp(s_jmpNoCPUID, 1);
50 static jmp_buf s_jmpNoSSE2;
51 static void SigIllHandlerSSE2(
int)
53 longjmp(s_jmpNoSSE2, 1);
60 #if defined(CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY) 89 volatile bool result =
true;
91 volatile SigHandler oldHandler = signal(SIGILL, SigIllHandlerCPUID);
92 if (oldHandler == SIG_ERR)
96 volatile sigset_t oldMask;
97 if (sigprocmask(0, NULL, (sigset_t*)&oldMask))
101 if (setjmp(s_jmpNoCPUID))
109 # if CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64 110 "pushq %%rbx; cpuid; mov %%ebx, %%edi; popq %%rbx" 112 "push %%ebx; cpuid; mov %%ebx, %%edi; pop %%ebx" 114 :
"=a" (output[0]),
"=D" (output[1]),
"=c" (output[2]),
"=d" (output[3])
115 :
"a" (input),
"c" (0)
121 sigprocmask(SIG_SETMASK, (sigset_t*)&oldMask, NULL);
124 signal(SIGILL, oldHandler);
131 static bool TrySSE2()
133 #if CRYPTOPP_BOOL_X64 135 #elif defined(CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY) 138 #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE 140 #elif CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE 141 __m128i
x = _mm_setzero_si128();
142 return _mm_cvtsi128_si32(x) == 0;
154 volatile bool result =
true;
156 volatile SigHandler oldHandler = signal(SIGILL, SigIllHandlerSSE2);
157 if (oldHandler == SIG_ERR)
161 volatile sigset_t oldMask;
162 if (sigprocmask(0, NULL, (sigset_t*)&oldMask))
166 if (setjmp(s_jmpNoSSE2))
170 #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE 171 __asm __volatile (
"por %xmm0, %xmm0");
172 #elif CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE 173 __m128i
x = _mm_setzero_si128();
174 result = _mm_cvtsi128_si32(x) == 0;
179 sigprocmask(SIG_SETMASK, (sigset_t*)&oldMask, NULL);
182 signal(SIGILL, oldHandler);
195 static inline bool IsIntel(
const word32 output[4])
198 return (output[1] == 0x756e6547) &&
199 (output[2] == 0x6c65746e) &&
200 (output[3] == 0x49656e69);
203 static inline bool IsAMD(
const word32 output[4])
206 return (output[1] == 0x68747541) &&
207 (output[2] == 0x444D4163) &&
208 (output[3] == 0x69746E65);
211 static inline bool IsVIA(
const word32 output[4])
214 return (output[1] == 0x746e6543) &&
215 (output[2] == 0x736c7561) &&
216 (output[3] == 0x48727561);
219 #if HAVE_GCC_CONSTRUCTOR1 221 #elif HAVE_GCC_CONSTRUCTOR0 224 void DetectX86Features()
227 word32 cpuid[4], cpuid1[4];
228 if (!CpuId(0, cpuid))
230 if (!CpuId(1, cpuid1))
233 g_hasMMX = (cpuid1[3] & (1 << 23)) != 0;
234 if ((cpuid1[3] & (1 << 26)) != 0)
235 g_hasSSE2 = TrySSE2();
236 g_hasSSSE3 = g_hasSSE2 && (cpuid1[2] & (1<<9));
237 g_hasSSE4 = g_hasSSE2 && ((cpuid1[2] & (1<<19)) && (cpuid1[2] & (1<<20)));
238 g_hasAESNI = g_hasSSE2 && (cpuid1[2] & (1<<25));
239 g_hasCLMUL = g_hasSSE2 && (cpuid1[2] & (1<<1));
241 if ((cpuid1[3] & (1 << 25)) != 0)
246 CpuId(0x080000000, cpuid2);
247 if (cpuid2[0] >= 0x080000001)
249 CpuId(0x080000001, cpuid2);
250 g_hasISSE = (cpuid2[3] & (1 << 22)) != 0;
256 static const unsigned int RDRAND_FLAG = (1 << 30);
257 static const unsigned int RDSEED_FLAG = (1 << 18);
258 static const unsigned int SHA_FLAG = (1 << 29);
260 g_isP4 = ((cpuid1[0] >> 8) & 0xf) == 0xf;
261 g_cacheLineSize = 8 *
GETBYTE(cpuid1[1], 1);
262 g_hasRDRAND = !!(cpuid1[2] & RDRAND_FLAG);
267 if (CpuId(7, cpuid3))
269 g_hasRDSEED = !!(cpuid3[1] & RDSEED_FLAG);
270 g_hasSHA = !!(cpuid3[1] & SHA_FLAG);
274 else if (IsAMD(cpuid))
276 static const unsigned int RDRAND_FLAG = (1 << 30);
279 g_hasRDRAND = !!(cpuid[2] & RDRAND_FLAG);
281 CpuId(0x80000005, cpuid);
282 g_cacheLineSize =
GETBYTE(cpuid[2], 0);
284 else if (IsVIA(cpuid))
286 static const unsigned int RNG_FLAGS = (0x3 << 2);
287 static const unsigned int ACE_FLAGS = (0x3 << 6);
288 static const unsigned int ACE2_FLAGS = (0x3 << 8);
289 static const unsigned int PHE_FLAGS = (0x3 << 10);
290 static const unsigned int PMM_FLAGS = (0x3 << 12);
292 CpuId(0xC0000000, cpuid);
293 if (cpuid[0] >= 0xC0000001)
296 CpuId(0xC0000001, cpuid);
297 g_hasPadlockRNG = !!(cpuid[3] & RNG_FLAGS);
298 g_hasPadlockACE = !!(cpuid[3] & ACE_FLAGS);
299 g_hasPadlockACE2 = !!(cpuid[3] & ACE2_FLAGS);
300 g_hasPadlockPHE = !!(cpuid[3] & PHE_FLAGS);
301 g_hasPadlockPMM = !!(cpuid[3] & PMM_FLAGS);
305 if (!g_cacheLineSize)
308 *((
volatile bool*)&g_x86DetectionDone) =
true;
311 #elif (CRYPTOPP_BOOL_ARM32 || CRYPTOPP_BOOL_ARM64) 332 #ifndef CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY 335 static jmp_buf s_jmpNoNEON;
336 static void SigIllHandlerNEON(
int)
338 longjmp(s_jmpNoNEON, 1);
341 static jmp_buf s_jmpNoPMULL;
342 static void SigIllHandlerPMULL(
int)
344 longjmp(s_jmpNoPMULL, 1);
347 static jmp_buf s_jmpNoCRC32;
348 static void SigIllHandlerCRC32(
int)
350 longjmp(s_jmpNoCRC32, 1);
353 static jmp_buf s_jmpNoAES;
354 static void SigIllHandlerAES(
int)
356 longjmp(s_jmpNoAES, 1);
359 static jmp_buf s_jmpNoSHA1;
360 static void SigIllHandlerSHA1(
int)
362 longjmp(s_jmpNoSHA1, 1);
365 static jmp_buf s_jmpNoSHA2;
366 static void SigIllHandlerSHA2(
int)
368 longjmp(s_jmpNoSHA2, 1);
371 #endif // Not CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY 373 static bool TryNEON()
375 #if (CRYPTOPP_BOOL_NEON_INTRINSICS_AVAILABLE) 376 # if defined(CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY) 377 volatile bool result =
true;
380 uint32_t v1[4] = {1,1,1,1};
381 uint32x4_t x1 = vld1q_u32(v1);
382 uint64_t v2[2] = {1,1};
383 uint64x2_t x2 = vld1q_u64(v2);
385 uint32x4_t x3 = vdupq_n_u32(2);
386 x3 = vsetq_lane_u32(vgetq_lane_u32(x1,0),x3,0);
387 x3 = vsetq_lane_u32(vgetq_lane_u32(x1,3),x3,3);
388 uint64x2_t x4 = vdupq_n_u64(2);
389 x4 = vsetq_lane_u64(vgetq_lane_u64(x2,0),x4,0);
390 x4 = vsetq_lane_u64(vgetq_lane_u64(x2,1),x4,1);
392 result = !!(vgetq_lane_u32(x3,0) | vgetq_lane_u64(x4,1));
402 volatile bool result =
true;
404 volatile SigHandler oldHandler = signal(SIGILL, SigIllHandlerNEON);
405 if (oldHandler == SIG_ERR)
408 volatile sigset_t oldMask;
409 if (sigprocmask(0, NULL, (sigset_t*)&oldMask))
412 if (setjmp(s_jmpNoNEON))
416 uint32_t v1[4] = {1,1,1,1};
417 uint32x4_t x1 = vld1q_u32(v1);
418 uint64_t v2[2] = {1,1};
419 uint64x2_t x2 = vld1q_u64(v2);
421 uint32x4_t x3 = {0,0,0,0};
422 x3 = vsetq_lane_u32(vgetq_lane_u32(x1,0),x3,0);
423 x3 = vsetq_lane_u32(vgetq_lane_u32(x1,3),x3,3);
424 uint64x2_t x4 = {0,0};
425 x4 = vsetq_lane_u64(vgetq_lane_u64(x2,0),x4,0);
426 x4 = vsetq_lane_u64(vgetq_lane_u64(x2,1),x4,1);
429 result = !!(vgetq_lane_u32(x3,0) | vgetq_lane_u64(x4,1));
432 sigprocmask(SIG_SETMASK, (sigset_t*)&oldMask, NULL);
433 signal(SIGILL, oldHandler);
438 #endif // CRYPTOPP_BOOL_NEON_INTRINSICS_AVAILABLE 441 static bool TryPMULL()
443 #if (CRYPTOPP_BOOL_ARM_CRYPTO_INTRINSICS_AVAILABLE) 444 # if defined(CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY) 445 volatile bool result =
true;
448 const poly64_t
a1={2}, b1={3};
449 const poly64x2_t
a2={4,5}, b2={6,7};
450 const poly64x2_t
a3={0x8080808080808080,0xa0a0a0a0a0a0a0a0}, b3={0xc0c0c0c0c0c0c0c0, 0xe0e0e0e0e0e0e0e0};
452 const poly128_t
r1 = vmull_p64(a1, b1);
453 const poly128_t
r2 = vmull_high_p64(a2, b2);
454 const poly128_t r3 = vmull_high_p64(a3, b3);
457 const uint64x2_t&
t1 = vreinterpretq_u64_p128(r1);
458 const uint64x2_t&
t2 = vreinterpretq_u64_p128(r2);
459 const uint64x2_t&
t3 = vreinterpretq_u64_p128(r3);
461 result = !!(vgetq_lane_u64(t1,0) == 0x06 && vgetq_lane_u64(t1,1) == 0x00 && vgetq_lane_u64(t2,0) == 0x1b &&
462 vgetq_lane_u64(t2,1) == 0x00 && vgetq_lane_u64(t3,0) == 0x6c006c006c006c00 && vgetq_lane_u64(t3,1) == 0x6c006c006c006c00);
472 volatile bool result =
true;
474 volatile SigHandler oldHandler = signal(SIGILL, SigIllHandlerPMULL);
475 if (oldHandler == SIG_ERR)
478 volatile sigset_t oldMask;
479 if (sigprocmask(0, NULL, (sigset_t*)&oldMask))
482 if (setjmp(s_jmpNoPMULL))
486 const poly64_t
a1={2}, b1={3};
487 const poly64x2_t
a2={4,5}, b2={6,7};
488 const poly64x2_t
a3={0x8080808080808080,0xa0a0a0a0a0a0a0a0}, b3={0xc0c0c0c0c0c0c0c0, 0xe0e0e0e0e0e0e0e0};
490 const poly128_t
r1 = vmull_p64(a1, b1);
491 const poly128_t
r2 = vmull_high_p64(a2, b2);
492 const poly128_t r3 = vmull_high_p64(a3, b3);
495 const uint64x2_t&
t1 = (uint64x2_t)(r1);
496 const uint64x2_t&
t2 = (uint64x2_t)(r2);
497 const uint64x2_t&
t3 = (uint64x2_t)(r3);
499 result = !!(vgetq_lane_u64(t1,0) == 0x06 && vgetq_lane_u64(t1,1) == 0x00 && vgetq_lane_u64(t2,0) == 0x1b &&
500 vgetq_lane_u64(t2,1) == 0x00 && vgetq_lane_u64(t3,0) == 0x6c006c006c006c00 && vgetq_lane_u64(t3,1) == 0x6c006c006c006c00);
503 sigprocmask(SIG_SETMASK, (sigset_t*)&oldMask, NULL);
504 signal(SIGILL, oldHandler);
509 #endif // CRYPTOPP_BOOL_ARM_CRYPTO_INTRINSICS_AVAILABLE 512 static bool TryCRC32()
514 #if (CRYPTOPP_BOOL_ARM_CRC32_INTRINSICS_AVAILABLE) 515 # if defined(CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY) 516 volatile bool result =
true;
534 volatile bool result =
true;
536 volatile SigHandler oldHandler = signal(SIGILL, SigIllHandlerCRC32);
537 if (oldHandler == SIG_ERR)
540 volatile sigset_t oldMask;
541 if (sigprocmask(0, NULL, (sigset_t*)&oldMask))
544 if (setjmp(s_jmpNoCRC32))
557 sigprocmask(SIG_SETMASK, (sigset_t*)&oldMask, NULL);
558 signal(SIGILL, oldHandler);
563 #endif // CRYPTOPP_BOOL_ARM_CRC32_INTRINSICS_AVAILABLE 568 #if (CRYPTOPP_BOOL_ARM_CRYPTO_INTRINSICS_AVAILABLE) 569 # if defined(CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY) 570 volatile bool result =
true;
574 uint8x16_t
data = vdupq_n_u8(0), key = vdupq_n_u8(0);
575 uint8x16_t
r1 = vaeseq_u8(data, key);
576 uint8x16_t
r2 = vaesdq_u8(data, key);
578 result = !!(vgetq_lane_u8(r1,0) | vgetq_lane_u8(r2,7));
588 volatile bool result =
true;
590 volatile SigHandler oldHandler = signal(SIGILL, SigIllHandlerAES);
591 if (oldHandler == SIG_ERR)
594 volatile sigset_t oldMask;
595 if (sigprocmask(0, NULL, (sigset_t*)&oldMask))
598 if (setjmp(s_jmpNoAES))
602 uint8x16_t
data = vdupq_n_u8(0), key = vdupq_n_u8(0);
603 uint8x16_t
r1 = vaeseq_u8(data, key);
604 uint8x16_t
r2 = vaesdq_u8(data, key);
607 result = !!(vgetq_lane_u8(r1,0) | vgetq_lane_u8(r2,7));
610 sigprocmask(SIG_SETMASK, (sigset_t*)&oldMask, NULL);
611 signal(SIGILL, oldHandler);
616 #endif // CRYPTOPP_BOOL_ARM_CRYPTO_INTRINSICS_AVAILABLE 619 static bool TrySHA1()
621 #if (CRYPTOPP_BOOL_ARM_CRYPTO_INTRINSICS_AVAILABLE) 622 # if defined(CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY) 623 volatile bool result =
true;
626 uint32x4_t data1 = {1,2,3,4}, data2 = {5,6,7,8}, data3 = {9,10,11,12};
628 uint32x4_t
r1 = vsha1cq_u32 (data1, 0, data2);
629 uint32x4_t
r2 = vsha1mq_u32 (data1, 0, data2);
630 uint32x4_t r3 = vsha1pq_u32 (data1, 0, data2);
631 uint32x4_t r4 = vsha1su0q_u32 (data1, data2, data3);
632 uint32x4_t r5 = vsha1su1q_u32 (data1, data2);
634 result = !!(vgetq_lane_u32(r1,0) | vgetq_lane_u32(r2,1) | vgetq_lane_u32(r3,2) | vgetq_lane_u32(r4,3) | vgetq_lane_u32(r5,0));
644 volatile bool result =
true;
646 volatile SigHandler oldHandler = signal(SIGILL, SigIllHandlerSHA1);
647 if (oldHandler == SIG_ERR)
650 volatile sigset_t oldMask;
651 if (sigprocmask(0, NULL, (sigset_t*)&oldMask))
654 if (setjmp(s_jmpNoSHA1))
658 uint32x4_t data1 = {1,2,3,4}, data2 = {5,6,7,8}, data3 = {9,10,11,12};
660 uint32x4_t
r1 = vsha1cq_u32 (data1, 0, data2);
661 uint32x4_t
r2 = vsha1mq_u32 (data1, 0, data2);
662 uint32x4_t r3 = vsha1pq_u32 (data1, 0, data2);
663 uint32x4_t r4 = vsha1su0q_u32 (data1, data2, data3);
664 uint32x4_t r5 = vsha1su1q_u32 (data1, data2);
667 result = !!(vgetq_lane_u32(r1,0) | vgetq_lane_u32(r2,1) | vgetq_lane_u32(r3,2) | vgetq_lane_u32(r4,3) | vgetq_lane_u32(r5,0));
670 sigprocmask(SIG_SETMASK, (sigset_t*)&oldMask, NULL);
671 signal(SIGILL, oldHandler);
676 #endif // CRYPTOPP_BOOL_ARM_CRYPTO_INTRINSICS_AVAILABLE 679 static bool TrySHA2()
681 #if (CRYPTOPP_BOOL_ARM_CRYPTO_INTRINSICS_AVAILABLE) 682 # if defined(CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY) 683 volatile bool result =
true;
686 uint32x4_t data1 = {1,2,3,4}, data2 = {5,6,7,8}, data3 = {9,10,11,12};
688 uint32x4_t
r1 = vsha256hq_u32 (data1, data2, data3);
689 uint32x4_t
r2 = vsha256h2q_u32 (data1, data2, data3);
690 uint32x4_t r3 = vsha256su0q_u32 (data1, data2);
691 uint32x4_t r4 = vsha256su1q_u32 (data1, data2, data3);
693 result = !!(vgetq_lane_u32(r1,0) | vgetq_lane_u32(r2,1) | vgetq_lane_u32(r3,2) | vgetq_lane_u32(r4,3));
703 volatile bool result =
true;
705 volatile SigHandler oldHandler = signal(SIGILL, SigIllHandlerSHA2);
706 if (oldHandler == SIG_ERR)
709 volatile sigset_t oldMask;
710 if (sigprocmask(0, NULL, (sigset_t*)&oldMask))
713 if (setjmp(s_jmpNoSHA2))
717 uint32x4_t data1 = {1,2,3,4}, data2 = {5,6,7,8}, data3 = {9,10,11,12};
719 uint32x4_t
r1 = vsha256hq_u32 (data1, data2, data3);
720 uint32x4_t
r2 = vsha256h2q_u32 (data1, data2, data3);
721 uint32x4_t r3 = vsha256su0q_u32 (data1, data2);
722 uint32x4_t r4 = vsha256su1q_u32 (data1, data2, data3);
725 result = !!(vgetq_lane_u32(r1,0) | vgetq_lane_u32(r2,1) | vgetq_lane_u32(r3,2) | vgetq_lane_u32(r4,3));
728 sigprocmask(SIG_SETMASK, (sigset_t*)&oldMask, NULL);
729 signal(SIGILL, oldHandler);
734 #endif // CRYPTOPP_BOOL_ARM_CRYPTO_INTRINSICS_AVAILABLE 737 #if HAVE_GCC_CONSTRUCTOR1 739 #elif HAVE_GCC_CONSTRUCTOR0 742 void DetectArmFeatures()
745 g_hasNEON = TryNEON();
746 g_hasPMULL = TryPMULL();
747 g_hasCRC32 = TryCRC32();
749 g_hasSHA1 = TrySHA1();
750 g_hasSHA2 = TrySHA2();
752 *((
volatile bool*)&g_ArmDetectionDone) =
true;
#define CRYPTOPP_SECTION_INIT
Utility functions for the Crypto++ library.
#define CRYPTOPP_INIT_PRIORITY
#define NAMESPACE_BEGIN(x)
Library configuration file.
#define EXCEPTION_EXECUTE_HANDLER
FascTransaction __attribute__
#define CRYPTOPP_L1_CACHE_LINE_SIZE
Functions for CPU features and intrinsics.