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