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