libcrypto: recognize HW acceleration support on arm64

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

libcrypto: recognize HW acceleration support on arm64

Patrick Wildt-3
Hi,

this diff adds the necessary helpers to arm64 so that libcrypto knows
which of the hardware crypto features are available on the machine.
Those helpers are used by the existing and matching armv7 code.

ok?

Patrick

diff --git a/lib/libcrypto/arch/aarch64/Makefile.inc b/lib/libcrypto/arch/aarch64/Makefile.inc
index 8742504f2d4..972e5536b5e 100644
--- a/lib/libcrypto/arch/aarch64/Makefile.inc
+++ b/lib/libcrypto/arch/aarch64/Makefile.inc
@@ -26,3 +26,6 @@ ${f}.S: ${LCRYPTO_SRC}/${dir}/asm/${f}.pl
  /usr/bin/perl \
  ${LCRYPTO_SRC}/${dir}/asm/${f}.pl void ${.TARGET} > ${.TARGET}
 .endfor
+
+CFLAGS+= -DOPENSSL_CPUID_OBJ
+SRCS+= arm64cpuid.S armcap.c
diff --git a/lib/libcrypto/arm64cpuid.S b/lib/libcrypto/arm64cpuid.S
new file mode 100644
index 00000000000..5eeff91c6ea
--- /dev/null
+++ b/lib/libcrypto/arm64cpuid.S
@@ -0,0 +1,47 @@
+#include "arm_arch.h"
+
+.text
+.arch armv8-a+crypto+sha3
+
+.align 5
+.globl _armv7_neon_probe
+.type _armv7_neon_probe,%function
+_armv7_neon_probe:
+ orr v15.16b, v15.16b, v15.16b
+ ret
+.size _armv7_neon_probe,.-_armv7_neon_probe
+
+.globl _armv8_aes_probe
+.type _armv8_aes_probe,%function
+_armv8_aes_probe:
+ aese v0.16b, v0.16b
+ ret
+.size _armv8_aes_probe,.-_armv8_aes_probe
+
+.globl _armv8_sha1_probe
+.type _armv8_sha1_probe,%function
+_armv8_sha1_probe:
+ sha1h s0, s0
+ ret
+.size _armv8_sha1_probe,.-_armv8_sha1_probe
+
+.globl _armv8_sha256_probe
+.type _armv8_sha256_probe,%function
+_armv8_sha256_probe:
+ sha256su0 v0.4s, v0.4s
+ ret
+.size _armv8_sha256_probe,.-_armv8_sha256_probe
+
+.globl _armv8_pmull_probe
+.type _armv8_pmull_probe,%function
+_armv8_pmull_probe:
+ pmull v0.1q, v0.1d, v0.1d
+ ret
+.size _armv8_pmull_probe,.-_armv8_pmull_probe
+
+.globl _armv8_sha512_probe
+.type _armv8_sha512_probe,%function
+_armv8_sha512_probe:
+ sha512su0 v0.2d,v0.2d
+ ret
+.size _armv8_sha512_probe,.-_armv8_sha512_probe
diff --git a/lib/libcrypto/arm_arch.h b/lib/libcrypto/arm_arch.h
index a64c6da46eb..bb137e6a48e 100644
--- a/lib/libcrypto/arm_arch.h
+++ b/lib/libcrypto/arm_arch.h
@@ -17,7 +17,11 @@
    * gcc/config/arm/arm.c. On a side note it defines
    * __ARMEL__/__ARMEB__ for little-/big-endian.
    */
-#  if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || \
+#  if defined(__ARM_ARCH)
+#   define __ARM_ARCH__ __ARM_ARCH
+#  elif defined(__ARM_ARCH_8A__)
+#   define __ARM_ARCH__ 8
+#  elif defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || \
  defined(__ARM_ARCH_7R__)|| defined(__ARM_ARCH_7M__) || \
  defined(__ARM_ARCH_7EM__)
 #   define __ARM_ARCH__ 7

Reply | Threaded
Open this post in threaded view
|

Re: libcrypto: recognize HW acceleration support on arm64

Mark Kettenis
> Date: Wed, 19 Jun 2019 07:13:19 +0200
> From: Patrick Wildt <[hidden email]>
>
> Hi,
>
> this diff adds the necessary helpers to arm64 so that libcrypto knows
> which of the hardware crypto features are available on the machine.
> Those helpers are used by the existing and matching armv7 code.
>
> ok?

No objections to the diff per se, but unless I'm missing something,
there currently isn't any assembly code that takes advantage of this
for arm64.  The armv7 code is 32-bit code so I don't think you can use
any of it in 64-bit mode.

> diff --git a/lib/libcrypto/arch/aarch64/Makefile.inc b/lib/libcrypto/arch/aarch64/Makefile.inc
> index 8742504f2d4..972e5536b5e 100644
> --- a/lib/libcrypto/arch/aarch64/Makefile.inc
> +++ b/lib/libcrypto/arch/aarch64/Makefile.inc
> @@ -26,3 +26,6 @@ ${f}.S: ${LCRYPTO_SRC}/${dir}/asm/${f}.pl
>   /usr/bin/perl \
>   ${LCRYPTO_SRC}/${dir}/asm/${f}.pl void ${.TARGET} > ${.TARGET}
>  .endfor
> +
> +CFLAGS+= -DOPENSSL_CPUID_OBJ
> +SRCS+= arm64cpuid.S armcap.c
> diff --git a/lib/libcrypto/arm64cpuid.S b/lib/libcrypto/arm64cpuid.S
> new file mode 100644
> index 00000000000..5eeff91c6ea
> --- /dev/null
> +++ b/lib/libcrypto/arm64cpuid.S
> @@ -0,0 +1,47 @@
> +#include "arm_arch.h"
> +
> +.text
> +.arch armv8-a+crypto+sha3
> +
> +.align 5
> +.globl _armv7_neon_probe
> +.type _armv7_neon_probe,%function
> +_armv7_neon_probe:
> + orr v15.16b, v15.16b, v15.16b
> + ret
> +.size _armv7_neon_probe,.-_armv7_neon_probe
> +
> +.globl _armv8_aes_probe
> +.type _armv8_aes_probe,%function
> +_armv8_aes_probe:
> + aese v0.16b, v0.16b
> + ret
> +.size _armv8_aes_probe,.-_armv8_aes_probe
> +
> +.globl _armv8_sha1_probe
> +.type _armv8_sha1_probe,%function
> +_armv8_sha1_probe:
> + sha1h s0, s0
> + ret
> +.size _armv8_sha1_probe,.-_armv8_sha1_probe
> +
> +.globl _armv8_sha256_probe
> +.type _armv8_sha256_probe,%function
> +_armv8_sha256_probe:
> + sha256su0 v0.4s, v0.4s
> + ret
> +.size _armv8_sha256_probe,.-_armv8_sha256_probe
> +
> +.globl _armv8_pmull_probe
> +.type _armv8_pmull_probe,%function
> +_armv8_pmull_probe:
> + pmull v0.1q, v0.1d, v0.1d
> + ret
> +.size _armv8_pmull_probe,.-_armv8_pmull_probe
> +
> +.globl _armv8_sha512_probe
> +.type _armv8_sha512_probe,%function
> +_armv8_sha512_probe:
> + sha512su0 v0.2d,v0.2d
> + ret
> +.size _armv8_sha512_probe,.-_armv8_sha512_probe
> diff --git a/lib/libcrypto/arm_arch.h b/lib/libcrypto/arm_arch.h
> index a64c6da46eb..bb137e6a48e 100644
> --- a/lib/libcrypto/arm_arch.h
> +++ b/lib/libcrypto/arm_arch.h
> @@ -17,7 +17,11 @@
>     * gcc/config/arm/arm.c. On a side note it defines
>     * __ARMEL__/__ARMEB__ for little-/big-endian.
>     */
> -#  if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || \
> +#  if defined(__ARM_ARCH)
> +#   define __ARM_ARCH__ __ARM_ARCH
> +#  elif defined(__ARM_ARCH_8A__)
> +#   define __ARM_ARCH__ 8
> +#  elif defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || \
>   defined(__ARM_ARCH_7R__)|| defined(__ARM_ARCH_7M__) || \
>   defined(__ARM_ARCH_7EM__)
>  #   define __ARM_ARCH__ 7
>
>

Reply | Threaded
Open this post in threaded view
|

Re: libcrypto: recognize HW acceleration support on arm64

Patrick Wildt-3
On Wed, Jun 19, 2019 at 09:25:27AM +0200, Mark Kettenis wrote:

> > Date: Wed, 19 Jun 2019 07:13:19 +0200
> > From: Patrick Wildt <[hidden email]>
> >
> > Hi,
> >
> > this diff adds the necessary helpers to arm64 so that libcrypto knows
> > which of the hardware crypto features are available on the machine.
> > Those helpers are used by the existing and matching armv7 code.
> >
> > ok?
>
> No objections to the diff per se, but unless I'm missing something,
> there currently isn't any assembly code that takes advantage of this
> for arm64.  The armv7 code is 32-bit code so I don't think you can use
> any of it in 64-bit mode.

No, you're right, at the moment there's no acceleration support for
arm64 in our tree.  But OpenSSL has more of that, even before their
license change, so I can easily pull that in step by step.

Reply | Threaded
Open this post in threaded view
|

Re: libcrypto: recognize HW acceleration support on arm64

Remco
In reply to this post by Patrick Wildt-3
On 19-06-19 07:13, Patrick Wildt wrote:

> Hi,
>
> this diff adds the necessary helpers to arm64 so that libcrypto knows
> which of the hardware crypto features are available on the machine.
> Those helpers are used by the existing and matching armv7 code.
>
> ok?
>
> Patrick
>

Does it make sense to query the ID_AA64PFR0_EL1 and ID_AA64ISAR0_EL1
system registers for that using the mrs instruction ?

I've only got a Linux system to play with and it's not clear to me how
to specify these registers with the mrs instruction on that system. I
resorted to encoding the instructions directly into the assembly code as
a byte sequence. I don't know if this also applies to OpenBSD.

In case you're interested, these functions seem to return reasonable
results on the one hardware board I have. It does crash on qemu though
with an "Illegal instruction" message.


.arch armv8-a


.text
.p2align 5
.globl cpuid_get_id_aa64isar0_el1
cpuid_get_id_aa64isar0_el1:

   # ID_AA64ISAR0_EL1:
   # op0  op1  CRn   CRm   op2
   # 11   000  0000  0110  000

   # mrs  x0, ID_AA64ISAR0_EL1
   # 1101 0101 0011 1000 0000 0110 0000 0000
   .byte 0x00, 0x06, 0x38, 0xd5

   ret

.size cpuid_get_id_aa64isar0_el1, .-cpuid_get_id_aa64isar0_el1
.type cpuid_get_id_aa64isar0_el1, @function


.text
.p2align 5
.globl cpuid_get_id_aa64pfr0_el1
cpuid_get_id_aa64pfr0_el1:

   # ID_AA64PFR0_EL1:
   # op0  op1  CRn   CRm   op2
   # 11   000  0000  0100  000

   # mrs  x0, ID_AA64PFR0_EL1
   # 1101 0101 0011 1000 0000 0100 0000 0000
   .byte 0x00, 0x04, 0x38, 0xd5

   ret

.size cpuid_get_id_aa64pfr0_el1, .-cpuid_get_id_aa64pfr0_el1
.type cpuid_get_id_aa64pfr0_el1, @function

Reply | Threaded
Open this post in threaded view
|

Re: libcrypto: recognize HW acceleration support on arm64

Patrick Wildt-3
On Thu, Jun 20, 2019 at 11:21:20AM +0200, Remco wrote:

> On 19-06-19 07:13, Patrick Wildt wrote:
> > Hi,
> >
> > this diff adds the necessary helpers to arm64 so that libcrypto knows
> > which of the hardware crypto features are available on the machine.
> > Those helpers are used by the existing and matching armv7 code.
> >
> > ok?
> >
> > Patrick
> >
>
> Does it make sense to query the ID_AA64PFR0_EL1 and ID_AA64ISAR0_EL1 system
> registers for that using the mrs instruction ?

It looks like those indeed encode enough information to figure it out,
but apparently the registers are not readable from userland, only from
EL1 and above.

The armv7 code works the same like this diff for arm64, where the
instruction is executed and if it traps we know it's not supported.
This way it fits right in.

Patrick