summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/arch
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/arch')
-rw-r--r--src/lib/libcrypto/arch/aarch64/Makefile.inc4
-rw-r--r--src/lib/libcrypto/arch/aarch64/arm64_arch.h59
-rw-r--r--src/lib/libcrypto/arch/aarch64/arm64cap.c88
-rw-r--r--src/lib/libcrypto/arch/aarch64/arm64cpuid.S47
-rw-r--r--src/lib/libcrypto/arch/arm/arm_arch.h59
-rw-r--r--src/lib/libcrypto/arch/arm/armcap.c88
-rw-r--r--src/lib/libcrypto/arch/arm/armv4cpuid.S165
7 files changed, 508 insertions, 2 deletions
diff --git a/src/lib/libcrypto/arch/aarch64/Makefile.inc b/src/lib/libcrypto/arch/aarch64/Makefile.inc
index d3d33e5941..48a340a6a2 100644
--- a/src/lib/libcrypto/arch/aarch64/Makefile.inc
+++ b/src/lib/libcrypto/arch/aarch64/Makefile.inc
@@ -1,4 +1,4 @@
1# $OpenBSD: Makefile.inc,v 1.2 2019/07/02 19:31:28 patrick Exp $ 1# $OpenBSD: Makefile.inc,v 1.3 2022/03/23 15:13:31 tb Exp $
2 2
3# aarch64-specific libcrypto build rules 3# aarch64-specific libcrypto build rules
4 4
@@ -28,4 +28,4 @@ ${f}.S: ${LCRYPTO_SRC}/${dir}/asm/${f}.pl
28.endfor 28.endfor
29 29
30CFLAGS+= -DOPENSSL_CPUID_OBJ 30CFLAGS+= -DOPENSSL_CPUID_OBJ
31SRCS+= arm64cpuid.S armcap.c 31SRCS+= arm64cpuid.S arm64cap.c
diff --git a/src/lib/libcrypto/arch/aarch64/arm64_arch.h b/src/lib/libcrypto/arch/aarch64/arm64_arch.h
new file mode 100644
index 0000000000..7f35acaa7d
--- /dev/null
+++ b/src/lib/libcrypto/arch/aarch64/arm64_arch.h
@@ -0,0 +1,59 @@
1/* $OpenBSD: arm64_arch.h,v 1.1 2022/03/23 15:13:31 tb Exp $ */
2#ifndef __ARM_ARCH_H__
3#define __ARM_ARCH_H__
4
5#if !defined(__ARM_ARCH__)
6# if defined(__CC_ARM)
7# define __ARM_ARCH__ __TARGET_ARCH_ARM
8# if defined(__BIG_ENDIAN)
9# define __ARMEB__
10# else
11# define __ARMEL__
12# endif
13# elif defined(__GNUC__)
14 /*
15 * Why doesn't gcc define __ARM_ARCH__? Instead it defines
16 * bunch of below macros. See all_architectures[] table in
17 * gcc/config/arm/arm.c. On a side note it defines
18 * __ARMEL__/__ARMEB__ for little-/big-endian.
19 */
20# if defined(__ARM_ARCH)
21# define __ARM_ARCH__ __ARM_ARCH
22# elif defined(__ARM_ARCH_8A__)
23# define __ARM_ARCH__ 8
24# elif defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || \
25 defined(__ARM_ARCH_7R__)|| defined(__ARM_ARCH_7M__) || \
26 defined(__ARM_ARCH_7EM__)
27# define __ARM_ARCH__ 7
28# elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || \
29 defined(__ARM_ARCH_6K__)|| defined(__ARM_ARCH_6M__) || \
30 defined(__ARM_ARCH_6Z__)|| defined(__ARM_ARCH_6ZK__) || \
31 defined(__ARM_ARCH_6T2__)
32# define __ARM_ARCH__ 6
33# elif defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) || \
34 defined(__ARM_ARCH_5E__)|| defined(__ARM_ARCH_5TE__) || \
35 defined(__ARM_ARCH_5TEJ__)
36# define __ARM_ARCH__ 5
37# elif defined(__ARM_ARCH_4__) || defined(__ARM_ARCH_4T__)
38# define __ARM_ARCH__ 4
39# else
40# error "unsupported ARM architecture"
41# endif
42# endif
43#endif
44
45#if !defined(__ASSEMBLER__)
46extern unsigned int OPENSSL_armcap_P;
47
48#define ARMV7_NEON (1<<0)
49#define ARMV8_AES (1<<1)
50#define ARMV8_SHA1 (1<<2)
51#define ARMV8_SHA256 (1<<3)
52#define ARMV8_PMULL (1<<4)
53#endif
54
55#if defined(__OpenBSD__)
56#define __STRICT_ALIGNMENT
57#endif
58
59#endif
diff --git a/src/lib/libcrypto/arch/aarch64/arm64cap.c b/src/lib/libcrypto/arch/aarch64/arm64cap.c
new file mode 100644
index 0000000000..b541ac31b9
--- /dev/null
+++ b/src/lib/libcrypto/arch/aarch64/arm64cap.c
@@ -0,0 +1,88 @@
1/* $OpenBSD: arm64cap.c,v 1.1 2022/03/23 15:13:31 tb 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 "arm64_arch.h"
10
11unsigned int OPENSSL_armcap_P;
12
13#if __ARM_ARCH__ >= 7
14static sigset_t all_masked;
15
16static sigjmp_buf ill_jmp;
17 static void ill_handler (int sig) { siglongjmp(ill_jmp, sig);
18}
19
20/*
21 * Following subroutines could have been inlined, but it's not all
22 * ARM compilers support inline assembler...
23 */
24void _armv7_neon_probe(void);
25void _armv8_aes_probe(void);
26void _armv8_sha1_probe(void);
27void _armv8_sha256_probe(void);
28void _armv8_pmull_probe(void);
29#endif
30
31#if defined(__GNUC__) && __GNUC__>=2
32void OPENSSL_cpuid_setup(void) __attribute__((constructor));
33#endif
34
35void
36OPENSSL_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}
diff --git a/src/lib/libcrypto/arch/aarch64/arm64cpuid.S b/src/lib/libcrypto/arch/aarch64/arm64cpuid.S
new file mode 100644
index 0000000000..d267ad6897
--- /dev/null
+++ b/src/lib/libcrypto/arch/aarch64/arm64cpuid.S
@@ -0,0 +1,47 @@
1#include "arm64_arch.h"
2
3.text
4.arch armv8-a+crypto+sha3
5
6.align 5
7.globl _armv7_neon_probe
8.type _armv7_neon_probe,%function
9_armv7_neon_probe:
10 orr v15.16b, v15.16b, v15.16b
11 ret
12.size _armv7_neon_probe,.-_armv7_neon_probe
13
14.globl _armv8_aes_probe
15.type _armv8_aes_probe,%function
16_armv8_aes_probe:
17 aese v0.16b, v0.16b
18 ret
19.size _armv8_aes_probe,.-_armv8_aes_probe
20
21.globl _armv8_sha1_probe
22.type _armv8_sha1_probe,%function
23_armv8_sha1_probe:
24 sha1h s0, s0
25 ret
26.size _armv8_sha1_probe,.-_armv8_sha1_probe
27
28.globl _armv8_sha256_probe
29.type _armv8_sha256_probe,%function
30_armv8_sha256_probe:
31 sha256su0 v0.4s, v0.4s
32 ret
33.size _armv8_sha256_probe,.-_armv8_sha256_probe
34
35.globl _armv8_pmull_probe
36.type _armv8_pmull_probe,%function
37_armv8_pmull_probe:
38 pmull v0.1q, v0.1d, v0.1d
39 ret
40.size _armv8_pmull_probe,.-_armv8_pmull_probe
41
42.globl _armv8_sha512_probe
43.type _armv8_sha512_probe,%function
44_armv8_sha512_probe:
45 sha512su0 v0.2d,v0.2d
46 ret
47.size _armv8_sha512_probe,.-_armv8_sha512_probe
diff --git a/src/lib/libcrypto/arch/arm/arm_arch.h b/src/lib/libcrypto/arch/arm/arm_arch.h
new file mode 100644
index 0000000000..5ac3b935f1
--- /dev/null
+++ b/src/lib/libcrypto/arch/arm/arm_arch.h
@@ -0,0 +1,59 @@
1/* $OpenBSD: arm_arch.h,v 1.1 2022/03/23 15:13:31 tb Exp $ */
2#ifndef __ARM_ARCH_H__
3#define __ARM_ARCH_H__
4
5#if !defined(__ARM_ARCH__)
6# if defined(__CC_ARM)
7# define __ARM_ARCH__ __TARGET_ARCH_ARM
8# if defined(__BIG_ENDIAN)
9# define __ARMEB__
10# else
11# define __ARMEL__
12# endif
13# elif defined(__GNUC__)
14 /*
15 * Why doesn't gcc define __ARM_ARCH__? Instead it defines
16 * bunch of below macros. See all_architectures[] table in
17 * gcc/config/arm/arm.c. On a side note it defines
18 * __ARMEL__/__ARMEB__ for little-/big-endian.
19 */
20# if defined(__ARM_ARCH)
21# define __ARM_ARCH__ __ARM_ARCH
22# elif defined(__ARM_ARCH_8A__)
23# define __ARM_ARCH__ 8
24# elif defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || \
25 defined(__ARM_ARCH_7R__)|| defined(__ARM_ARCH_7M__) || \
26 defined(__ARM_ARCH_7EM__)
27# define __ARM_ARCH__ 7
28# elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || \
29 defined(__ARM_ARCH_6K__)|| defined(__ARM_ARCH_6M__) || \
30 defined(__ARM_ARCH_6Z__)|| defined(__ARM_ARCH_6ZK__) || \
31 defined(__ARM_ARCH_6T2__)
32# define __ARM_ARCH__ 6
33# elif defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) || \
34 defined(__ARM_ARCH_5E__)|| defined(__ARM_ARCH_5TE__) || \
35 defined(__ARM_ARCH_5TEJ__)
36# define __ARM_ARCH__ 5
37# elif defined(__ARM_ARCH_4__) || defined(__ARM_ARCH_4T__)
38# define __ARM_ARCH__ 4
39# else
40# error "unsupported ARM architecture"
41# endif
42# endif
43#endif
44
45#if !defined(__ASSEMBLER__)
46extern unsigned int OPENSSL_armcap_P;
47
48#define ARMV7_NEON (1<<0)
49#define ARMV8_AES (1<<1)
50#define ARMV8_SHA1 (1<<2)
51#define ARMV8_SHA256 (1<<3)
52#define ARMV8_PMULL (1<<4)
53#endif
54
55#if defined(__OpenBSD__)
56#define __STRICT_ALIGNMENT
57#endif
58
59#endif
diff --git a/src/lib/libcrypto/arch/arm/armcap.c b/src/lib/libcrypto/arch/arm/armcap.c
new file mode 100644
index 0000000000..e1a721b71f
--- /dev/null
+++ b/src/lib/libcrypto/arch/arm/armcap.c
@@ -0,0 +1,88 @@
1/* $OpenBSD: armcap.c,v 1.1 2022/03/23 15:13:31 tb 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
11unsigned int OPENSSL_armcap_P;
12
13#if __ARM_ARCH__ >= 7
14static sigset_t all_masked;
15
16static sigjmp_buf ill_jmp;
17 static void ill_handler (int sig) { siglongjmp(ill_jmp, sig);
18}
19
20/*
21 * Following subroutines could have been inlined, but it's not all
22 * ARM compilers support inline assembler...
23 */
24void _armv7_neon_probe(void);
25void _armv8_aes_probe(void);
26void _armv8_sha1_probe(void);
27void _armv8_sha256_probe(void);
28void _armv8_pmull_probe(void);
29#endif
30
31#if defined(__GNUC__) && __GNUC__>=2
32void OPENSSL_cpuid_setup(void) __attribute__((constructor));
33#endif
34
35void
36OPENSSL_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}
diff --git a/src/lib/libcrypto/arch/arm/armv4cpuid.S b/src/lib/libcrypto/arch/arm/armv4cpuid.S
new file mode 100644
index 0000000000..bb9abafebe
--- /dev/null
+++ b/src/lib/libcrypto/arch/arm/armv4cpuid.S
@@ -0,0 +1,165 @@
1#include "arm_arch.h"
2
3.text
4#if defined(__thumb2__) && !defined(__APPLE__)
5.syntax unified
6.thumb
7#else
8.code 32
9#undef __thumb2__
10#endif
11
12.align 5
13.globl OPENSSL_atomic_add
14.type OPENSSL_atomic_add,%function
15OPENSSL_atomic_add:
16#if __ARM_ARCH__>=6
17.Ladd: ldrex r2,[r0]
18 add r3,r2,r1
19 strex r2,r3,[r0]
20 cmp r2,#0
21 bne .Ladd
22 mov r0,r3
23 bx lr
24#else
25 stmdb sp!,{r4,r5,r6,lr}
26 ldr r2,.Lspinlock
27 adr r3,.Lspinlock
28 mov r4,r0
29 mov r5,r1
30 add r6,r3,r2 @ &spinlock
31 b .+8
32.Lspin: bl sched_yield
33 mov r0,#-1
34 swp r0,r0,[r6]
35 cmp r0,#0
36 bne .Lspin
37
38 ldr r2,[r4]
39 add r2,r2,r5
40 str r2,[r4]
41 str r0,[r6] @ release spinlock
42 ldmia sp!,{r4,r5,r6,lr}
43 tst lr,#1
44 moveq pc,lr
45.word 0xe12fff1e @ bx lr
46#endif
47.size OPENSSL_atomic_add,.-OPENSSL_atomic_add
48
49#if __ARM_ARCH__>=7
50.arch armv7-a
51.fpu neon
52
53.align 5
54.globl _armv7_neon_probe
55.type _armv7_neon_probe,%function
56_armv7_neon_probe:
57 vorr q0,q0,q0
58 bx lr
59.size _armv7_neon_probe,.-_armv7_neon_probe
60
61.globl _armv8_aes_probe
62.type _armv8_aes_probe,%function
63_armv8_aes_probe:
64#if defined(__thumb2__) && !defined(__APPLE__)
65.byte 0xb0,0xff,0x00,0x03 @ aese.8 q0,q0
66#else
67.byte 0x00,0x03,0xb0,0xf3 @ aese.8 q0,q0
68#endif
69 bx lr
70.size _armv8_aes_probe,.-_armv8_aes_probe
71
72.globl _armv8_sha1_probe
73.type _armv8_sha1_probe,%function
74_armv8_sha1_probe:
75#if defined(__thumb2__) && !defined(__APPLE__)
76.byte 0x00,0xef,0x40,0x0c @ sha1c.32 q0,q0,q0
77#else
78.byte 0x40,0x0c,0x00,0xf2 @ sha1c.32 q0,q0,q0
79#endif
80 bx lr
81.size _armv8_sha1_probe,.-_armv8_sha1_probe
82
83.globl _armv8_sha256_probe
84.type _armv8_sha256_probe,%function
85_armv8_sha256_probe:
86#if defined(__thumb2__) && !defined(__APPLE__)
87.byte 0x00,0xff,0x40,0x0c @ sha256h.32 q0,q0,q0
88#else
89.byte 0x40,0x0c,0x00,0xf3 @ sha256h.32 q0,q0,q0
90#endif
91 bx lr
92.size _armv8_sha256_probe,.-_armv8_sha256_probe
93.globl _armv8_pmull_probe
94.type _armv8_pmull_probe,%function
95_armv8_pmull_probe:
96#if defined(__thumb2__) && !defined(__APPLE__)
97.byte 0xa0,0xef,0x00,0x0e @ vmull.p64 q0,d0,d0
98#else
99.byte 0x00,0x0e,0xa0,0xf2 @ vmull.p64 q0,d0,d0
100#endif
101 bx lr
102.size _armv8_pmull_probe,.-_armv8_pmull_probe
103#endif
104
105.globl OPENSSL_wipe_cpu
106.type OPENSSL_wipe_cpu,%function
107OPENSSL_wipe_cpu:
108#if __ARM_ARCH__>=7
109 ldr r0,.LOPENSSL_armcap
110 adr r1,.LOPENSSL_armcap
111 ldr r0,[r1,r0]
112#ifdef __APPLE__
113 ldr r0,[r0]
114#endif
115#endif
116 eor r2,r2,r2
117 eor r3,r3,r3
118 eor ip,ip,ip
119#if __ARM_ARCH__>=7
120 tst r0,#1
121 beq .Lwipe_done
122 veor q0, q0, q0
123 veor q1, q1, q1
124 veor q2, q2, q2
125 veor q3, q3, q3
126 veor q8, q8, q8
127 veor q9, q9, q9
128 veor q10, q10, q10
129 veor q11, q11, q11
130 veor q12, q12, q12
131 veor q13, q13, q13
132 veor q14, q14, q14
133 veor q15, q15, q15
134.Lwipe_done:
135#endif
136 mov r0,sp
137#if __ARM_ARCH__>=5
138 bx lr
139#else
140 tst lr,#1
141 moveq pc,lr
142.word 0xe12fff1e @ bx lr
143#endif
144.size OPENSSL_wipe_cpu,.-OPENSSL_wipe_cpu
145
146.align 5
147#if __ARM_ARCH__>=7
148.LOPENSSL_armcap:
149.word OPENSSL_armcap_P-.
150#endif
151#if __ARM_ARCH__>=6
152.align 5
153#else
154.Lspinlock:
155.word atomic_add_spinlock-.Lspinlock
156.align 5
157
158.data
159.align 2
160atomic_add_spinlock:
161.word 0
162#endif
163
164.comm OPENSSL_armcap_P,4,4
165.hidden OPENSSL_armcap_P