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