summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/libcrypto/arch/aarch64/Makefile.inc12
-rw-r--r--src/lib/libcrypto/arch/aarch64/arm64_arch.h59
-rw-r--r--src/lib/libcrypto/arch/aarch64/arm64cap.c138
-rw-r--r--src/lib/libcrypto/arch/aarch64/arm64cpuid.S53
-rw-r--r--src/lib/libcrypto/arch/aarch64/crypto_arch.h17
-rw-r--r--src/lib/libcrypto/arch/aarch64/crypto_cpu_caps.c96
6 files changed, 114 insertions, 261 deletions
diff --git a/src/lib/libcrypto/arch/aarch64/Makefile.inc b/src/lib/libcrypto/arch/aarch64/Makefile.inc
index a17ef7f5a9..20a634dc99 100644
--- a/src/lib/libcrypto/arch/aarch64/Makefile.inc
+++ b/src/lib/libcrypto/arch/aarch64/Makefile.inc
@@ -1,15 +1,7 @@
1# $OpenBSD: Makefile.inc,v 1.13 2024/03/29 07:24:09 jsing Exp $ 1# $OpenBSD: Makefile.inc,v 1.14 2024/11/08 13:34:24 jsing Exp $
2 2
3# aarch64-specific libcrypto build rules 3# aarch64-specific libcrypto build rules
4 4
5.for dir f in ${SSLASM} 5SRCS += crypto_cpu_caps.c
6SRCS+= ${f}.S
7GENERATED+=${f}.S
8${f}.S: ${LCRYPTO_SRC}/${dir}/asm/${f}.pl
9 /usr/bin/perl \
10 ${LCRYPTO_SRC}/${dir}/asm/${f}.pl void ${.TARGET} > ${.TARGET}
11.endfor
12 6
13CFLAGS+= -DOPENSSL_CPUID_OBJ
14AFLAGS+= -mmark-bti-property 7AFLAGS+= -mmark-bti-property
15SRCS+= arm64cpuid.S arm64cap.c
diff --git a/src/lib/libcrypto/arch/aarch64/arm64_arch.h b/src/lib/libcrypto/arch/aarch64/arm64_arch.h
deleted file mode 100644
index 7f35acaa7d..0000000000
--- a/src/lib/libcrypto/arch/aarch64/arm64_arch.h
+++ /dev/null
@@ -1,59 +0,0 @@
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
deleted file mode 100644
index aeacebfcb4..0000000000
--- a/src/lib/libcrypto/arch/aarch64/arm64cap.c
+++ /dev/null
@@ -1,138 +0,0 @@
1/* $OpenBSD: arm64cap.c,v 1.4 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#if defined(__OpenBSD__)
10#include <sys/sysctl.h>
11#include <machine/cpu.h> /* CPU_ID_AA64ISAR0 */
12#endif
13
14#include "arm64_arch.h"
15
16/* ID_AA64ISAR0_EL1 required for OPENSSL_cpuid_setup */
17#define ID_AA64ISAR0_AES_SHIFT 4
18#define ID_AA64ISAR0_AES_MASK (0xf << ID_AA64ISAR0_AES_SHIFT)
19#define ID_AA64ISAR0_AES(x) ((x) & ID_AA64ISAR0_AES_MASK)
20#define ID_AA64ISAR0_AES_BASE (0x1 << ID_AA64ISAR0_AES_SHIFT)
21#define ID_AA64ISAR0_AES_PMULL (0x2 << ID_AA64ISAR0_AES_SHIFT)
22#define ID_AA64ISAR0_SHA1_SHIFT 8
23#define ID_AA64ISAR0_SHA1_MASK (0xf << ID_AA64ISAR0_SHA1_SHIFT)
24#define ID_AA64ISAR0_SHA1(x) ((x) & ID_AA64ISAR0_SHA1_MASK)
25#define ID_AA64ISAR0_SHA1_BASE (0x1 << ID_AA64ISAR0_SHA1_SHIFT)
26#define ID_AA64ISAR0_SHA2_SHIFT 12
27#define ID_AA64ISAR0_SHA2_MASK (0xf << ID_AA64ISAR0_SHA2_SHIFT)
28#define ID_AA64ISAR0_SHA2(x) ((x) & ID_AA64ISAR0_SHA2_MASK)
29#define ID_AA64ISAR0_SHA2_BASE (0x1 << ID_AA64ISAR0_SHA2_SHIFT)
30
31unsigned int OPENSSL_armcap_P;
32
33#if defined(CPU_ID_AA64ISAR0)
34void
35OPENSSL_cpuid_setup(void)
36{
37 int isar0_mib[] = { CTL_MACHDEP, CPU_ID_AA64ISAR0 };
38 size_t len = sizeof(uint64_t);
39 uint64_t cpu_id = 0;
40
41 if (OPENSSL_armcap_P != 0)
42 return;
43
44 if (sysctl(isar0_mib, 2, &cpu_id, &len, NULL, 0) < 0)
45 return;
46
47 OPENSSL_armcap_P |= ARMV7_NEON;
48
49 if (ID_AA64ISAR0_AES(cpu_id) >= ID_AA64ISAR0_AES_BASE)
50 OPENSSL_armcap_P |= ARMV8_AES;
51
52 if (ID_AA64ISAR0_AES(cpu_id) >= ID_AA64ISAR0_AES_PMULL)
53 OPENSSL_armcap_P |= ARMV8_PMULL;
54
55 if (ID_AA64ISAR0_SHA1(cpu_id) >= ID_AA64ISAR0_SHA1_BASE)
56 OPENSSL_armcap_P |= ARMV8_SHA1;
57
58 if (ID_AA64ISAR0_SHA2(cpu_id) >= ID_AA64ISAR0_SHA2_BASE)
59 OPENSSL_armcap_P |= ARMV8_SHA256;
60}
61#else
62#if __ARM_ARCH__ >= 7
63static sigset_t all_masked;
64
65static sigjmp_buf ill_jmp;
66
67static void
68ill_handler(int sig)
69{
70 siglongjmp(ill_jmp, sig);
71}
72
73/*
74 * Following subroutines could have been inlined, but it's not all
75 * ARM compilers support inline assembler...
76 */
77void _armv7_neon_probe(void);
78void _armv8_aes_probe(void);
79void _armv8_sha1_probe(void);
80void _armv8_sha256_probe(void);
81void _armv8_pmull_probe(void);
82#endif
83
84void
85OPENSSL_cpuid_setup(void)
86{
87#if __ARM_ARCH__ >= 7
88 struct sigaction ill_oact, ill_act;
89 sigset_t oset;
90#endif
91 static int trigger = 0;
92
93 if (trigger)
94 return;
95 trigger = 1;
96
97 OPENSSL_armcap_P = 0;
98
99#if __ARM_ARCH__ >= 7
100 sigfillset(&all_masked);
101 sigdelset(&all_masked, SIGILL);
102 sigdelset(&all_masked, SIGTRAP);
103 sigdelset(&all_masked, SIGFPE);
104 sigdelset(&all_masked, SIGBUS);
105 sigdelset(&all_masked, SIGSEGV);
106
107 memset(&ill_act, 0, sizeof(ill_act));
108 ill_act.sa_handler = ill_handler;
109 ill_act.sa_mask = all_masked;
110
111 sigprocmask(SIG_SETMASK, &ill_act.sa_mask, &oset);
112 sigaction(SIGILL, &ill_act, &ill_oact);
113
114 if (sigsetjmp(ill_jmp, 1) == 0) {
115 _armv7_neon_probe();
116 OPENSSL_armcap_P |= ARMV7_NEON;
117 if (sigsetjmp(ill_jmp, 1) == 0) {
118 _armv8_pmull_probe();
119 OPENSSL_armcap_P |= ARMV8_PMULL | ARMV8_AES;
120 } else if (sigsetjmp(ill_jmp, 1) == 0) {
121 _armv8_aes_probe();
122 OPENSSL_armcap_P |= ARMV8_AES;
123 }
124 if (sigsetjmp(ill_jmp, 1) == 0) {
125 _armv8_sha1_probe();
126 OPENSSL_armcap_P |= ARMV8_SHA1;
127 }
128 if (sigsetjmp(ill_jmp, 1) == 0) {
129 _armv8_sha256_probe();
130 OPENSSL_armcap_P |= ARMV8_SHA256;
131 }
132 }
133
134 sigaction (SIGILL, &ill_oact, NULL);
135 sigprocmask(SIG_SETMASK, &oset, NULL);
136#endif
137}
138#endif
diff --git a/src/lib/libcrypto/arch/aarch64/arm64cpuid.S b/src/lib/libcrypto/arch/aarch64/arm64cpuid.S
deleted file mode 100644
index 96a9c76fb1..0000000000
--- a/src/lib/libcrypto/arch/aarch64/arm64cpuid.S
+++ /dev/null
@@ -1,53 +0,0 @@
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 bti c
11 orr v15.16b, v15.16b, v15.16b
12 ret
13.size _armv7_neon_probe,.-_armv7_neon_probe
14
15.globl _armv8_aes_probe
16.type _armv8_aes_probe,%function
17_armv8_aes_probe:
18 bti c
19 aese v0.16b, v0.16b
20 ret
21.size _armv8_aes_probe,.-_armv8_aes_probe
22
23.globl _armv8_sha1_probe
24.type _armv8_sha1_probe,%function
25_armv8_sha1_probe:
26 bti c
27 sha1h s0, s0
28 ret
29.size _armv8_sha1_probe,.-_armv8_sha1_probe
30
31.globl _armv8_sha256_probe
32.type _armv8_sha256_probe,%function
33_armv8_sha256_probe:
34 bti c
35 sha256su0 v0.4s, v0.4s
36 ret
37.size _armv8_sha256_probe,.-_armv8_sha256_probe
38
39.globl _armv8_pmull_probe
40.type _armv8_pmull_probe,%function
41_armv8_pmull_probe:
42 bti c
43 pmull v0.1q, v0.1d, v0.1d
44 ret
45.size _armv8_pmull_probe,.-_armv8_pmull_probe
46
47.globl _armv8_sha512_probe
48.type _armv8_sha512_probe,%function
49_armv8_sha512_probe:
50 bti c
51 sha512su0 v0.2d,v0.2d
52 ret
53.size _armv8_sha512_probe,.-_armv8_sha512_probe
diff --git a/src/lib/libcrypto/arch/aarch64/crypto_arch.h b/src/lib/libcrypto/arch/aarch64/crypto_arch.h
index a3dd98d0ce..b0188c498a 100644
--- a/src/lib/libcrypto/arch/aarch64/crypto_arch.h
+++ b/src/lib/libcrypto/arch/aarch64/crypto_arch.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: crypto_arch.h,v 1.1 2024/08/11 13:02:39 jsing Exp $ */ 1/* $OpenBSD: crypto_arch.h,v 1.2 2024/11/08 13:34:24 jsing Exp $ */
2/* 2/*
3 * Copyright (c) 2024 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2024 Joel Sing <jsing@openbsd.org>
4 * 4 *
@@ -15,7 +15,22 @@
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */ 16 */
17 17
18#include <stdint.h>
19
18#ifndef HEADER_CRYPTO_ARCH_H 20#ifndef HEADER_CRYPTO_ARCH_H
19#define HEADER_CRYPTO_ARCH_H 21#define HEADER_CRYPTO_ARCH_H
20 22
23#define HAVE_CRYPTO_CPU_CAPS_INIT
24
25#ifndef __ASSEMBLER__
26extern uint64_t crypto_cpu_caps_aarch64;
27#endif
28
29#define CRYPTO_CPU_CAPS_AARCH64_AES (1ULL << 0)
30#define CRYPTO_CPU_CAPS_AARCH64_PMULL (1ULL << 1)
31#define CRYPTO_CPU_CAPS_AARCH64_SHA1 (1ULL << 2)
32#define CRYPTO_CPU_CAPS_AARCH64_SHA2 (1ULL << 3)
33#define CRYPTO_CPU_CAPS_AARCH64_SHA512 (1ULL << 4)
34#define CRYPTO_CPU_CAPS_AARCH64_SHA3 (1ULL << 5)
35
21#endif 36#endif
diff --git a/src/lib/libcrypto/arch/aarch64/crypto_cpu_caps.c b/src/lib/libcrypto/arch/aarch64/crypto_cpu_caps.c
new file mode 100644
index 0000000000..24ebfbdf2b
--- /dev/null
+++ b/src/lib/libcrypto/arch/aarch64/crypto_cpu_caps.c
@@ -0,0 +1,96 @@
1/* $OpenBSD: crypto_cpu_caps.c,v 1.1 2024/11/08 13:34:24 jsing Exp $ */
2/*
3 * Copyright (c) 2023 Joel Sing <jsing@openbsd.org>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#include <sys/types.h>
19#include <sys/sysctl.h>
20
21#include <machine/cpu.h>
22
23#include <stddef.h>
24#include <stdio.h>
25
26#include "crypto_arch.h"
27
28uint64_t crypto_cpu_caps_aarch64;
29
30static inline uint64_t
31extract_bits(uint64_t val, int start, int end)
32{
33 return (val >> end) & (1ULL << (1 + start - end)) - 1;
34}
35
36static uint64_t
37parse_isar0(uint64_t isar0)
38{
39 uint64_t caps = 0;
40 uint64_t feature;
41
42 /* AES - bits [7:4] */
43 feature = extract_bits(isar0, 7, 4);
44 if (feature >= 1)
45 caps |= CRYPTO_CPU_CAPS_AARCH64_AES;
46 if (feature >= 2)
47 caps |= CRYPTO_CPU_CAPS_AARCH64_PMULL;
48
49 /* SHA1 - bits [11:8] */
50 feature = extract_bits(isar0, 11, 8);
51 if (feature >= 1)
52 caps |= CRYPTO_CPU_CAPS_AARCH64_SHA1;
53
54 /* SHA2 - bits [15:12] */
55 feature = extract_bits(isar0, 15, 12);
56 if (feature >= 1)
57 caps |= CRYPTO_CPU_CAPS_AARCH64_SHA2;
58 if (feature >= 2)
59 caps |= CRYPTO_CPU_CAPS_AARCH64_SHA512;
60
61 /* SHA3 - bits [35:32] */
62 feature = extract_bits(isar0, 35, 32);
63 if (feature >= 1)
64 caps |= CRYPTO_CPU_CAPS_AARCH64_SHA3;
65
66 return caps;
67}
68
69static int
70read_isar0(uint64_t *isar0)
71{
72 uint64_t isar;
73 int mib[2];
74 size_t len;
75
76 mib[0] = CTL_MACHDEP;
77 mib[1] = CPU_ID_AA64ISAR0;
78 len = sizeof(isar);
79 if (sysctl(mib, 2, &isar, &len, NULL, 0) == -1)
80 return 0;
81
82 *isar0 = isar;
83
84 return 1;
85}
86
87void
88crypto_cpu_caps_init(void)
89{
90 uint64_t isar = 0;
91
92 if (!read_isar0(&isar))
93 return;
94
95 crypto_cpu_caps_aarch64 = parse_isar0(isar);
96}