Index: src/hwf-arm.c
--- src/hwf-arm.c.orig
+++ src/hwf-arm.c
@@ -27,6 +27,11 @@
 #if defined(HAVE_SYS_AUXV_H) && (defined(HAVE_GETAUXVAL) || \
     defined(HAVE_ELF_AUX_INFO))
 #include <sys/auxv.h>
+#elif defined(__OpenBSD__) && defined(__aarch64__)
+#include <sys/types.h>
+#include <sys/sysctl.h>
+#include <machine/cpu.h>
+#include <machine/armreg.h>
 #endif
 #if defined(__APPLE__) && defined(HAVE_SYS_SYSCTL_H) && \
     defined(HAVE_SYSCTLBYNAME)
@@ -66,7 +71,8 @@ static unsigned long getauxval(unsigned long type)
 
 #undef HAS_SYS_AT_HWCAP
 #if defined(__linux__) || \
-    (defined(HAVE_SYS_AUXV_H) && defined(HAVE_GETAUXVAL))
+    (defined(HAVE_SYS_AUXV_H) && defined(HAVE_GETAUXVAL)) || \
+    (defined(__OpenBSD__) && defined(__aarch64__))
 #define HAS_SYS_AT_HWCAP 1
 
 struct feature_map_s {
@@ -243,6 +249,29 @@ get_hwcap(unsigned int *hwcap, unsigned int *hwcap2)
       *hwcap2 = stored_hwcap2;
       return 0;
     }
+#elif defined(__OpenBSD__) && defined(__aarch64__)
+  {
+    const int isar0_mib[] = { CTL_MACHDEP, CPU_ID_AA64ISAR0 };
+    uint64_t isar0;
+    size_t len = sizeof(isar0);
+
+    stored_hwcap |= HWCAP_ASIMD;
+    hwcap_initialized = 1;
+    if (sysctl(isar0_mib, 2, &isar0, &len, NULL, 0) != -1)
+      {
+        if (ID_AA64ISAR0_AES(isar0) >= ID_AA64ISAR0_AES_BASE)
+          stored_hwcap |= HWCAP_AES;
+        if (ID_AA64ISAR0_AES(isar0) >= ID_AA64ISAR0_AES_PMULL)
+          stored_hwcap |= HWCAP_PMULL;
+        if (ID_AA64ISAR0_SHA1(isar0) >= ID_AA64ISAR0_SHA1_BASE)
+          stored_hwcap |= HWCAP_SHA1;
+        if (ID_AA64ISAR0_SHA2(isar0) >= ID_AA64ISAR0_SHA2_BASE)
+          stored_hwcap |= HWCAP_SHA2;
+      }
+    *hwcap = stored_hwcap;
+    *hwcap2 = stored_hwcap2;
+    return 0;
+  }
 #endif
 
   f = fopen("/proc/self/auxv", "r");
