131cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root#include <stdio.h> 231cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root#include <stdlib.h> 331cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root#include <string.h> 431cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root#include <setjmp.h> 531cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root#include <signal.h> 631cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root#include <crypto.h> 731cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root 831cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root#include "arm_arch.h" 931cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root 1031cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Rootunsigned int OPENSSL_armcap_P; 1131cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root 1231cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Rootstatic sigset_t all_masked; 1331cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root 1431cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Rootstatic sigjmp_buf ill_jmp; 1531cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Rootstatic void ill_handler (int sig) { siglongjmp(ill_jmp,sig); } 1631cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root 1731cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root/* 1831cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root * Following subroutines could have been inlined, but it's not all 1931cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root * ARM compilers support inline assembler... 2031cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root */ 2131cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Rootvoid _armv7_neon_probe(void); 223f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Rootvoid _armv8_aes_probe(void); 233f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Rootvoid _armv8_sha1_probe(void); 243f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Rootvoid _armv8_sha256_probe(void); 253f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Rootvoid _armv8_pmull_probe(void); 263f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Rootunsigned long _armv7_tick(void); 2731cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root 283f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Rootunsigned long OPENSSL_rdtsc(void) 2931cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root { 3031cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root if (OPENSSL_armcap_P & ARMV7_TICK) 3131cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root return _armv7_tick(); 3231cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root else 3331cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root return 0; 3431cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root } 3531cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root 363f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root/* 373f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root * Use a weak reference to getauxval() so we can use it if it is available but 383f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root * don't break the build if it is not. 393f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root */ 4031cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root#if defined(__GNUC__) && __GNUC__>=2 4131cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Rootvoid OPENSSL_cpuid_setup(void) __attribute__((constructor)); 423f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Rootextern unsigned long getauxval(unsigned long type) __attribute__((weak)); 433f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root#else 443f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Rootstatic unsigned long (*getauxval)(unsigned long) = NULL; 4531cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root#endif 463f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root 473f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root/* 483f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root * ARM puts the the feature bits for Crypto Extensions in AT_HWCAP2, whereas 493f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root * AArch64 used AT_HWCAP. 503f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root */ 513f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root#if defined(__arm__) || defined (__arm) 523f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root# define HWCAP 16 /* AT_HWCAP */ 533f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root# define HWCAP_NEON (1 << 12) 543f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root 553f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root# define HWCAP_CE 26 /* AT_HWCAP2 */ 563f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root# define HWCAP_CE_AES (1 << 0) 573f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root# define HWCAP_CE_PMULL (1 << 1) 583f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root# define HWCAP_CE_SHA1 (1 << 2) 593f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root# define HWCAP_CE_SHA256 (1 << 3) 603f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root#elif defined(__aarch64__) 613f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root# define HWCAP 16 /* AT_HWCAP */ 623f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root# define HWCAP_NEON (1 << 1) 633f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root 643f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root# define HWCAP_CE HWCAP 653f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root# define HWCAP_CE_AES (1 << 3) 663f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root# define HWCAP_CE_PMULL (1 << 4) 673f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root# define HWCAP_CE_SHA1 (1 << 5) 683f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root# define HWCAP_CE_SHA256 (1 << 6) 693f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root#endif 703f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root 7131cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Rootvoid OPENSSL_cpuid_setup(void) 7231cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root { 7331cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root char *e; 7431cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root struct sigaction ill_oact,ill_act; 7531cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root sigset_t oset; 7631cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root static int trigger=0; 7731cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root 7831cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root if (trigger) return; 7931cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root trigger=1; 8031cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root 8131cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root if ((e=getenv("OPENSSL_armcap"))) 8231cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root { 833f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root OPENSSL_armcap_P=(unsigned int)strtoul(e,NULL,0); 8431cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root return; 8531cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root } 8631cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root 8731cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root sigfillset(&all_masked); 8831cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root sigdelset(&all_masked,SIGILL); 8931cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root sigdelset(&all_masked,SIGTRAP); 9031cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root sigdelset(&all_masked,SIGFPE); 9131cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root sigdelset(&all_masked,SIGBUS); 9231cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root sigdelset(&all_masked,SIGSEGV); 9331cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root 9431cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root OPENSSL_armcap_P = 0; 9531cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root 9631cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root memset(&ill_act,0,sizeof(ill_act)); 9731cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root ill_act.sa_handler = ill_handler; 9831cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root ill_act.sa_mask = all_masked; 9931cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root 10031cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root sigprocmask(SIG_SETMASK,&ill_act.sa_mask,&oset); 10131cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root sigaction(SIGILL,&ill_act,&ill_oact); 10231cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root 1033f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root if (getauxval != NULL) 1043f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root { 1053f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root if (getauxval(HWCAP) & HWCAP_NEON) 1063f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root { 1073f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root unsigned long hwcap = getauxval(HWCAP_CE); 1083f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root 1093f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root OPENSSL_armcap_P |= ARMV7_NEON; 1103f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root 1113f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root if (hwcap & HWCAP_CE_AES) 1123f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root OPENSSL_armcap_P |= ARMV8_AES; 1133f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root 1143f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root if (hwcap & HWCAP_CE_PMULL) 1153f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root OPENSSL_armcap_P |= ARMV8_PMULL; 1163f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root 1173f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root if (hwcap & HWCAP_CE_SHA1) 1183f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root OPENSSL_armcap_P |= ARMV8_SHA1; 1193f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root 1203f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root if (hwcap & HWCAP_CE_SHA256) 1213f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root OPENSSL_armcap_P |= ARMV8_SHA256; 1223f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root } 1233f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root } 1243f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root else if (sigsetjmp(ill_jmp,1) == 0) 12531cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root { 12631cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root _armv7_neon_probe(); 12731cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root OPENSSL_armcap_P |= ARMV7_NEON; 1283f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root if (sigsetjmp(ill_jmp,1) == 0) 1293f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root { 1303f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root _armv8_pmull_probe(); 1313f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root OPENSSL_armcap_P |= ARMV8_PMULL|ARMV8_AES; 1323f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root } 1333f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root else if (sigsetjmp(ill_jmp,1) == 0) 1343f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root { 1353f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root _armv8_aes_probe(); 1363f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root OPENSSL_armcap_P |= ARMV8_AES; 1373f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root } 1383f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root if (sigsetjmp(ill_jmp,1) == 0) 1393f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root { 1403f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root _armv8_sha1_probe(); 1413f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root OPENSSL_armcap_P |= ARMV8_SHA1; 1423f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root } 1433f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root if (sigsetjmp(ill_jmp,1) == 0) 1443f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root { 1453f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root _armv8_sha256_probe(); 1463f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root OPENSSL_armcap_P |= ARMV8_SHA256; 1473f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root } 14831cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root } 14931cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root if (sigsetjmp(ill_jmp,1) == 0) 15031cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root { 15131cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root _armv7_tick(); 15231cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root OPENSSL_armcap_P |= ARMV7_TICK; 15331cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root } 15431cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root 15531cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root sigaction (SIGILL,&ill_oact,NULL); 15631cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root sigprocmask(SIG_SETMASK,&oset,NULL); 15731cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root } 158