armcap.c 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <setjmp.h>
  5. #include <signal.h>
  6. #include <crypto.h>
  7. #include "arm_arch.h"
  8. unsigned int OPENSSL_armcap_P;
  9. static sigset_t all_masked;
  10. static sigjmp_buf ill_jmp;
  11. static void ill_handler (int sig) { siglongjmp(ill_jmp,sig); }
  12. /*
  13. * Following subroutines could have been inlined, but it's not all
  14. * ARM compilers support inline assembler...
  15. */
  16. void _armv7_neon_probe(void);
  17. unsigned int _armv7_tick(void);
  18. void _armv8_aes_probe(void);
  19. void _armv8_sha1_probe(void);
  20. void _armv8_sha256_probe(void);
  21. void _armv8_pmull_probe(void);
  22. unsigned int OPENSSL_rdtsc(void)
  23. {
  24. if (OPENSSL_armcap_P|ARMV7_TICK)
  25. return _armv7_tick();
  26. else
  27. return 0;
  28. }
  29. #if defined(__GNUC__) && __GNUC__>=2
  30. void OPENSSL_cpuid_setup(void) __attribute__((constructor));
  31. #endif
  32. void OPENSSL_cpuid_setup(void)
  33. {
  34. char *e;
  35. struct sigaction ill_oact,ill_act;
  36. sigset_t oset;
  37. static int trigger=0;
  38. if (trigger) return;
  39. trigger=1;
  40. if ((e=getenv("OPENSSL_armcap")))
  41. {
  42. OPENSSL_armcap_P=strtoul(e,NULL,0);
  43. return;
  44. }
  45. sigfillset(&all_masked);
  46. sigdelset(&all_masked,SIGILL);
  47. sigdelset(&all_masked,SIGTRAP);
  48. sigdelset(&all_masked,SIGFPE);
  49. sigdelset(&all_masked,SIGBUS);
  50. sigdelset(&all_masked,SIGSEGV);
  51. OPENSSL_armcap_P = 0;
  52. memset(&ill_act,0,sizeof(ill_act));
  53. ill_act.sa_handler = ill_handler;
  54. ill_act.sa_mask = all_masked;
  55. sigprocmask(SIG_SETMASK,&ill_act.sa_mask,&oset);
  56. sigaction(SIGILL,&ill_act,&ill_oact);
  57. if (sigsetjmp(ill_jmp,1) == 0)
  58. {
  59. _armv7_neon_probe();
  60. OPENSSL_armcap_P |= ARMV7_NEON;
  61. #ifdef __aarch64__
  62. if (sigsetjmp(ill_jmp,1) == 0)
  63. {
  64. _armv8_pmull_probe();
  65. OPENSSL_armcap_P |= ARMV8_PMULL|ARMV8_AES;
  66. }
  67. else if (sigsetjmp(ill_jmp,1) == 0)
  68. {
  69. _armv8_aes_probe();
  70. OPENSSL_armcap_P |= ARMV8_AES;
  71. }
  72. if (sigsetjmp(ill_jmp,1) == 0)
  73. {
  74. _armv8_sha1_probe();
  75. OPENSSL_armcap_P |= ARMV8_SHA1;
  76. }
  77. if (sigsetjmp(ill_jmp,1) == 0)
  78. {
  79. _armv8_sha256_probe();
  80. OPENSSL_armcap_P |= ARMV8_SHA256;
  81. }
  82. #endif
  83. }
  84. if (sigsetjmp(ill_jmp,1) == 0)
  85. {
  86. _armv7_tick();
  87. OPENSSL_armcap_P |= ARMV7_TICK;
  88. }
  89. sigaction (SIGILL,&ill_oact,NULL);
  90. sigprocmask(SIG_SETMASK,&oset,NULL);
  91. }