Skip to contentSkip to conversation

arm: crypto: Add NEON optimized SHA-256

PATCH New Sami Tolvanen 5 participants 33 messages Mar 16, 2015 – Apr 3, 2015

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 arm: crypto: Add NEON optimized SHA-256

Add Andy Polyakov's NEON optimized SHA-256 implementation.

On Nexus 6, this implementation is ~2x faster than sha256-generic.

---
 arch/arm/crypto/Makefile            |    2 
 arch/arm/crypto/sha256-armv7-neon.S |  819 ++++++++++++++++++++++++++++++++++++
 arch/arm/crypto/sha256_neon_glue.c  |  201 ++++++++
 crypto/Kconfig                      |   12 
 4 files changed, 1034 insertions(+)
arch/arm/crypto/Makefile +2 -0
index b48fa34..316dba2 100644
@@ -6,12 +6,14 @@ obj-$(CONFIG_CRYPTO_AES_ARM) += aes-arm.o
 obj-$(CONFIG_CRYPTO_AES_ARM_BS) += aes-arm-bs.o
 obj-$(CONFIG_CRYPTO_SHA1_ARM) += sha1-arm.o
 obj-$(CONFIG_CRYPTO_SHA1_ARM_NEON) += sha1-arm-neon.o
+obj-$(CONFIG_CRYPTO_SHA256_ARM_NEON) += sha256-arm-neon.o
 obj-$(CONFIG_CRYPTO_SHA512_ARM_NEON) += sha512-arm-neon.o
 
 aes-arm-y	:= aes-armv4.o aes_glue.o
 aes-arm-bs-y	:= aesbs-core.o aesbs-glue.o
 sha1-arm-y	:= sha1-armv4-large.o sha1_glue.o
 sha1-arm-neon-y	:= sha1-armv7-neon.o sha1_neon_glue.o
+sha256-arm-neon-y := sha256-armv7-neon.o sha256_neon_glue.o
 sha512-arm-neon-y := sha512-armv7-neon.o sha512_neon_glue.o
 
 quiet_cmd_perl = PERL    $@
arch/arm/crypto/sha256-armv7-neon.S new file +819 -0

819 lines not on this page · raw message

arch/arm/crypto/sha256_neon_glue.c new file +201 -0

201 lines not on this page · raw message

crypto/Kconfig +12 -0
index 50f4da4..0505523 100644
@@ -610,6 +610,18 @@ config CRYPTO_SHA256
 	  This code also includes SHA-224, a 224 bit hash with 112 bits
 	  of security against collision attacks.
 
+config CRYPTO_SHA256_ARM_NEON
+	tristate "SHA256 digest algorithm (ARM NEON)"
+	depends on ARM && KERNEL_MODE_NEON && !CPU_BIG_ENDIAN
+	select CRYPTO_SHA256
+	select CRYPTO_HASH
+	help
+	  SHA-256 secure hash standard (DFIPS 180-2) implemented
+	  using ARM NEON instructions, when available.
+
+	  This version of SHA implements a 256 bit hash with 128 bits of
+	  security against collision attacks.
+
 config CRYPTO_SHA256_SPARC64
 	tristate "SHA224 and SHA256 digest algorithm (SPARC64)"
 	depends on SPARC64
#1 lore raw

PATCH 1/1 arm: crypto: Add NEON optimized SHA-256

Hello Sami,

Quoted 6 lines · Sami Tolvanen

Add Andy Polyakov's NEON optimized SHA-256 implementation.

On Nexus 6, this implementation is ~2x faster than sha256-generic.

Have you tested this code with the tcrypt.ko module?

Some more comments below

Quoted 32 lines
---
 arch/arm/crypto/Makefile            |    2
 arch/arm/crypto/sha256-armv7-neon.S |  819 ++++++++++++++++++++++++++++++++++++
 arch/arm/crypto/sha256_neon_glue.c  |  201 ++++++++
 crypto/Kconfig                      |   12
 4 files changed, 1034 insertions(+)
arch/arm/crypto/Makefile +2 -0
index b48fa34..316dba2 100644
@@ -6,12 +6,14 @@ obj-$(CONFIG_CRYPTO_AES_ARM) += aes-arm.o
 obj-$(CONFIG_CRYPTO_AES_ARM_BS) += aes-arm-bs.o
 obj-$(CONFIG_CRYPTO_SHA1_ARM) += sha1-arm.o
 obj-$(CONFIG_CRYPTO_SHA1_ARM_NEON) += sha1-arm-neon.o
+obj-$(CONFIG_CRYPTO_SHA256_ARM_NEON) += sha256-arm-neon.o
 obj-$(CONFIG_CRYPTO_SHA512_ARM_NEON) += sha512-arm-neon.o
 
 aes-arm-y      := aes-armv4.o aes_glue.o
 aes-arm-bs-y   := aesbs-core.o aesbs-glue.o
 sha1-arm-y     := sha1-armv4-large.o sha1_glue.o
 sha1-arm-neon-y        := sha1-armv7-neon.o sha1_neon_glue.o
+sha256-arm-neon-y := sha256-armv7-neon.o sha256_neon_glue.o
 sha512-arm-neon-y := sha512-armv7-neon.o sha512_neon_glue.o
 
 quiet_cmd_perl = PERL    $@
arch/arm/crypto/sha256-armv7-neon.S new file +0 -0
new file mode 100644
index 0000000..5ce04c2

arch/arm/crypto/sha256-armv7-neon.S line 9

Quoted 9 lines
arch/arm/crypto/sha256-armv7-neon.S new file +9 -0
@@ -0,0 +1,819 @@
+@ sha256-armv7-neon.S  -  ARM/NEON assembly implementation of SHA-256 transform
+@
+@ ====================================================================
+@ Written by Andy Polyakov <[email protected]> for the OpenSSL
+@ project. The module is, however, dual licensed under OpenSSL and
+@ CRYPTOGAMS licenses depending on where you obtain it. For further
+@ details see http://www.openssl.org/~appro/cryptogams/.
+@ ====================================================================
+

Did you talk to Andy about the license? I don't think this is permissible for the kernel as-is.

Quoted 28 lines
arch/arm/crypto/sha256-armv7-neon.S new file +28 -0
+#include <linux/linkage.h>
+
+.text
+.code   32
+.fpu neon
+
+.type  K256,%object
+.align 5
+K256:
+.word  0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5
+.word  0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5
+.word  0xd807aa98,0x12835b01,0x243185be,0x550c7dc3
+.word  0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174
+.word  0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc
+.word  0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da
+.word  0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7
+.word  0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967
+.word  0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13
+.word  0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85
+.word  0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3
+.word  0xd192e819,0xd6990624,0xf40e3585,0x106aa070
+.word  0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5
+.word  0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3
+.word  0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208
+.word  0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
+.size  K256,.-K256
+.word  0                               @ terminator
+.word  0

arch/arm/crypto/sha256-armv7-neon.S line 47

Quoted 10 lines
arch/arm/crypto/sha256-armv7-neon.S new file +10 -0
+.align 5
+
+.align 5
+ENTRY(sha256_transform_neon)
+       /* Input:
+        *      %r0: SHA256_CONTEXT
+        *      %r1: data
+        *      %r2: nblks
+        */
+       sub     r3,pc,#8                @ sha256_transform_neon

This is broken on thumb-2, use adr instead

Quoted 949 lines
arch/arm/crypto/sha256-armv7-neon.S new file +772 -0
+       add     r2,r1,r2,lsl#6  @ len to point at the end of inp
+
+       stmdb   sp!,{r4-r12,lr}
+
+       mov     r12,sp
+       sub     sp,sp,#16*4+16          @ alloca
+       sub     r14,r3,#256+32  @ K256
+       bic     sp,sp,#15               @ align for 128-bit stores
+
+       vld1.8          {q0},[r1]!
+       vld1.8          {q1},[r1]!
+       vld1.8          {q2},[r1]!
+       vld1.8          {q3},[r1]!
+       vld1.32         {q8},[r14,:128]!
+       vld1.32         {q9},[r14,:128]!
+       vld1.32         {q10},[r14,:128]!
+       vld1.32         {q11},[r14,:128]!
+       vrev32.8        q0,q0           @ yes, even on
+       str             r0,[sp,#64]
+       vrev32.8        q1,q1           @ big-endian
+       str             r1,[sp,#68]
+       mov             r1,sp
+       vrev32.8        q2,q2
+       str             r2,[sp,#72]
+       vrev32.8        q3,q3
+       str             r12,[sp,#76]            @ save original sp
+       vadd.i32        q8,q8,q0
+       vadd.i32        q9,q9,q1
+       vst1.32         {q8},[r1,:128]!
+       vadd.i32        q10,q10,q2
+       vst1.32         {q9},[r1,:128]!
+       vadd.i32        q11,q11,q3
+       vst1.32         {q10},[r1,:128]!
+       vst1.32         {q11},[r1,:128]!
+
+       ldmia           r0,{r4-r11}
+       sub             r1,r1,#64
+       ldr             r2,[sp,#0]
+       eor             r12,r12,r12
+       eor             r3,r5,r6
+       b               .L_00_48
+
+.align 4
+.L_00_48:
+       vext.8  q8,q0,q1,#4
+       add     r11,r11,r2
+       eor     r2,r9,r10
+       eor     r0,r8,r8,ror#5
+       vext.8  q9,q2,q3,#4
+       add     r4,r4,r12
+       and     r2,r2,r8
+       eor     r12,r0,r8,ror#19
+       vshr.u32        q10,q8,#7
+       eor     r0,r4,r4,ror#11
+       eor     r2,r2,r10
+       vadd.i32        q0,q0,q9
+       add     r11,r11,r12,ror#6
+       eor     r12,r4,r5
+       vshr.u32        q9,q8,#3
+       eor     r0,r0,r4,ror#20
+       add     r11,r11,r2
+       vsli.32 q10,q8,#25
+       ldr     r2,[sp,#4]
+       and     r3,r3,r12
+       vshr.u32        q11,q8,#18
+       add     r7,r7,r11
+       add     r11,r11,r0,ror#2
+       eor     r3,r3,r5
+       veor    q9,q9,q10
+       add     r10,r10,r2
+       vsli.32 q11,q8,#14
+       eor     r2,r8,r9
+       eor     r0,r7,r7,ror#5
+       vshr.u32        d24,d7,#17
+       add     r11,r11,r3
+       and     r2,r2,r7
+       veor    q9,q9,q11
+       eor     r3,r0,r7,ror#19
+       eor     r0,r11,r11,ror#11
+       vsli.32 d24,d7,#15
+       eor     r2,r2,r9
+       add     r10,r10,r3,ror#6
+       vshr.u32        d25,d7,#10
+       eor     r3,r11,r4
+       eor     r0,r0,r11,ror#20
+       vadd.i32        q0,q0,q9
+       add     r10,r10,r2
+       ldr     r2,[sp,#8]
+       veor    d25,d25,d24
+       and     r12,r12,r3
+       add     r6,r6,r10
+       vshr.u32        d24,d7,#19
+       add     r10,r10,r0,ror#2
+       eor     r12,r12,r4
+       vsli.32 d24,d7,#13
+       add     r9,r9,r2
+       eor     r2,r7,r8
+       veor    d25,d25,d24
+       eor     r0,r6,r6,ror#5
+       add     r10,r10,r12
+       vadd.i32        d0,d0,d25
+       and     r2,r2,r6
+       eor     r12,r0,r6,ror#19
+       vshr.u32        d24,d0,#17
+       eor     r0,r10,r10,ror#11
+       eor     r2,r2,r8
+       vsli.32 d24,d0,#15
+       add     r9,r9,r12,ror#6
+       eor     r12,r10,r11
+       vshr.u32        d25,d0,#10
+       eor     r0,r0,r10,ror#20
+       add     r9,r9,r2
+       veor    d25,d25,d24
+       ldr     r2,[sp,#12]
+       and     r3,r3,r12
+       vshr.u32        d24,d0,#19
+       add     r5,r5,r9
+       add     r9,r9,r0,ror#2
+       eor     r3,r3,r11
+       vld1.32 {q8},[r14,:128]!
+       add     r8,r8,r2
+       vsli.32 d24,d0,#13
+       eor     r2,r6,r7
+       eor     r0,r5,r5,ror#5
+       veor    d25,d25,d24
+       add     r9,r9,r3
+       and     r2,r2,r5
+       vadd.i32        d1,d1,d25
+       eor     r3,r0,r5,ror#19
+       eor     r0,r9,r9,ror#11
+       vadd.i32        q8,q8,q0
+       eor     r2,r2,r7
+       add     r8,r8,r3,ror#6
+       eor     r3,r9,r10
+       eor     r0,r0,r9,ror#20
+       add     r8,r8,r2
+       ldr     r2,[sp,#16]
+       and     r12,r12,r3
+       add     r4,r4,r8
+       vst1.32 {q8},[r1,:128]!
+       add     r8,r8,r0,ror#2
+       eor     r12,r12,r10
+       vext.8  q8,q1,q2,#4
+       add     r7,r7,r2
+       eor     r2,r5,r6
+       eor     r0,r4,r4,ror#5
+       vext.8  q9,q3,q0,#4
+       add     r8,r8,r12
+       and     r2,r2,r4
+       eor     r12,r0,r4,ror#19
+       vshr.u32        q10,q8,#7
+       eor     r0,r8,r8,ror#11
+       eor     r2,r2,r6
+       vadd.i32        q1,q1,q9
+       add     r7,r7,r12,ror#6
+       eor     r12,r8,r9
+       vshr.u32        q9,q8,#3
+       eor     r0,r0,r8,ror#20
+       add     r7,r7,r2
+       vsli.32 q10,q8,#25
+       ldr     r2,[sp,#20]
+       and     r3,r3,r12
+       vshr.u32        q11,q8,#18
+       add     r11,r11,r7
+       add     r7,r7,r0,ror#2
+       eor     r3,r3,r9
+       veor    q9,q9,q10
+       add     r6,r6,r2
+       vsli.32 q11,q8,#14
+       eor     r2,r4,r5
+       eor     r0,r11,r11,ror#5
+       vshr.u32        d24,d1,#17
+       add     r7,r7,r3
+       and     r2,r2,r11
+       veor    q9,q9,q11
+       eor     r3,r0,r11,ror#19
+       eor     r0,r7,r7,ror#11
+       vsli.32 d24,d1,#15
+       eor     r2,r2,r5
+       add     r6,r6,r3,ror#6
+       vshr.u32        d25,d1,#10
+       eor     r3,r7,r8
+       eor     r0,r0,r7,ror#20
+       vadd.i32        q1,q1,q9
+       add     r6,r6,r2
+       ldr     r2,[sp,#24]
+       veor    d25,d25,d24
+       and     r12,r12,r3
+       add     r10,r10,r6
+       vshr.u32        d24,d1,#19
+       add     r6,r6,r0,ror#2
+       eor     r12,r12,r8
+       vsli.32 d24,d1,#13
+       add     r5,r5,r2
+       eor     r2,r11,r4
+       veor    d25,d25,d24
+       eor     r0,r10,r10,ror#5
+       add     r6,r6,r12
+       vadd.i32        d2,d2,d25
+       and     r2,r2,r10
+       eor     r12,r0,r10,ror#19
+       vshr.u32        d24,d2,#17
+       eor     r0,r6,r6,ror#11
+       eor     r2,r2,r4
+       vsli.32 d24,d2,#15
+       add     r5,r5,r12,ror#6
+       eor     r12,r6,r7
+       vshr.u32        d25,d2,#10
+       eor     r0,r0,r6,ror#20
+       add     r5,r5,r2
+       veor    d25,d25,d24
+       ldr     r2,[sp,#28]
+       and     r3,r3,r12
+       vshr.u32        d24,d2,#19
+       add     r9,r9,r5
+       add     r5,r5,r0,ror#2
+       eor     r3,r3,r7
+       vld1.32 {q8},[r14,:128]!
+       add     r4,r4,r2
+       vsli.32 d24,d2,#13
+       eor     r2,r10,r11
+       eor     r0,r9,r9,ror#5
+       veor    d25,d25,d24
+       add     r5,r5,r3
+       and     r2,r2,r9
+       vadd.i32        d3,d3,d25
+       eor     r3,r0,r9,ror#19
+       eor     r0,r5,r5,ror#11
+       vadd.i32        q8,q8,q1
+       eor     r2,r2,r11
+       add     r4,r4,r3,ror#6
+       eor     r3,r5,r6
+       eor     r0,r0,r5,ror#20
+       add     r4,r4,r2
+       ldr     r2,[sp,#32]
+       and     r12,r12,r3
+       add     r8,r8,r4
+       vst1.32 {q8},[r1,:128]!
+       add     r4,r4,r0,ror#2
+       eor     r12,r12,r6
+       vext.8  q8,q2,q3,#4
+       add     r11,r11,r2
+       eor     r2,r9,r10
+       eor     r0,r8,r8,ror#5
+       vext.8  q9,q0,q1,#4
+       add     r4,r4,r12
+       and     r2,r2,r8
+       eor     r12,r0,r8,ror#19
+       vshr.u32        q10,q8,#7
+       eor     r0,r4,r4,ror#11
+       eor     r2,r2,r10
+       vadd.i32        q2,q2,q9
+       add     r11,r11,r12,ror#6
+       eor     r12,r4,r5
+       vshr.u32        q9,q8,#3
+       eor     r0,r0,r4,ror#20
+       add     r11,r11,r2
+       vsli.32 q10,q8,#25
+       ldr     r2,[sp,#36]
+       and     r3,r3,r12
+       vshr.u32        q11,q8,#18
+       add     r7,r7,r11
+       add     r11,r11,r0,ror#2
+       eor     r3,r3,r5
+       veor    q9,q9,q10
+       add     r10,r10,r2
+       vsli.32 q11,q8,#14
+       eor     r2,r8,r9
+       eor     r0,r7,r7,ror#5
+       vshr.u32        d24,d3,#17
+       add     r11,r11,r3
+       and     r2,r2,r7
+       veor    q9,q9,q11
+       eor     r3,r0,r7,ror#19
+       eor     r0,r11,r11,ror#11
+       vsli.32 d24,d3,#15
+       eor     r2,r2,r9
+       add     r10,r10,r3,ror#6
+       vshr.u32        d25,d3,#10
+       eor     r3,r11,r4
+       eor     r0,r0,r11,ror#20
+       vadd.i32        q2,q2,q9
+       add     r10,r10,r2
+       ldr     r2,[sp,#40]
+       veor    d25,d25,d24
+       and     r12,r12,r3
+       add     r6,r6,r10
+       vshr.u32        d24,d3,#19
+       add     r10,r10,r0,ror#2
+       eor     r12,r12,r4
+       vsli.32 d24,d3,#13
+       add     r9,r9,r2
+       eor     r2,r7,r8
+       veor    d25,d25,d24
+       eor     r0,r6,r6,ror#5
+       add     r10,r10,r12
+       vadd.i32        d4,d4,d25
+       and     r2,r2,r6
+       eor     r12,r0,r6,ror#19
+       vshr.u32        d24,d4,#17
+       eor     r0,r10,r10,ror#11
+       eor     r2,r2,r8
+       vsli.32 d24,d4,#15
+       add     r9,r9,r12,ror#6
+       eor     r12,r10,r11
+       vshr.u32        d25,d4,#10
+       eor     r0,r0,r10,ror#20
+       add     r9,r9,r2
+       veor    d25,d25,d24
+       ldr     r2,[sp,#44]
+       and     r3,r3,r12
+       vshr.u32        d24,d4,#19
+       add     r5,r5,r9
+       add     r9,r9,r0,ror#2
+       eor     r3,r3,r11
+       vld1.32 {q8},[r14,:128]!
+       add     r8,r8,r2
+       vsli.32 d24,d4,#13
+       eor     r2,r6,r7
+       eor     r0,r5,r5,ror#5
+       veor    d25,d25,d24
+       add     r9,r9,r3
+       and     r2,r2,r5
+       vadd.i32        d5,d5,d25
+       eor     r3,r0,r5,ror#19
+       eor     r0,r9,r9,ror#11
+       vadd.i32        q8,q8,q2
+       eor     r2,r2,r7
+       add     r8,r8,r3,ror#6
+       eor     r3,r9,r10
+       eor     r0,r0,r9,ror#20
+       add     r8,r8,r2
+       ldr     r2,[sp,#48]
+       and     r12,r12,r3
+       add     r4,r4,r8
+       vst1.32 {q8},[r1,:128]!
+       add     r8,r8,r0,ror#2
+       eor     r12,r12,r10
+       vext.8  q8,q3,q0,#4
+       add     r7,r7,r2
+       eor     r2,r5,r6
+       eor     r0,r4,r4,ror#5
+       vext.8  q9,q1,q2,#4
+       add     r8,r8,r12
+       and     r2,r2,r4
+       eor     r12,r0,r4,ror#19
+       vshr.u32        q10,q8,#7
+       eor     r0,r8,r8,ror#11
+       eor     r2,r2,r6
+       vadd.i32        q3,q3,q9
+       add     r7,r7,r12,ror#6
+       eor     r12,r8,r9
+       vshr.u32        q9,q8,#3
+       eor     r0,r0,r8,ror#20
+       add     r7,r7,r2
+       vsli.32 q10,q8,#25
+       ldr     r2,[sp,#52]
+       and     r3,r3,r12
+       vshr.u32        q11,q8,#18
+       add     r11,r11,r7
+       add     r7,r7,r0,ror#2
+       eor     r3,r3,r9
+       veor    q9,q9,q10
+       add     r6,r6,r2
+       vsli.32 q11,q8,#14
+       eor     r2,r4,r5
+       eor     r0,r11,r11,ror#5
+       vshr.u32        d24,d5,#17
+       add     r7,r7,r3
+       and     r2,r2,r11
+       veor    q9,q9,q11
+       eor     r3,r0,r11,ror#19
+       eor     r0,r7,r7,ror#11
+       vsli.32 d24,d5,#15
+       eor     r2,r2,r5
+       add     r6,r6,r3,ror#6
+       vshr.u32        d25,d5,#10
+       eor     r3,r7,r8
+       eor     r0,r0,r7,ror#20
+       vadd.i32        q3,q3,q9
+       add     r6,r6,r2
+       ldr     r2,[sp,#56]
+       veor    d25,d25,d24
+       and     r12,r12,r3
+       add     r10,r10,r6
+       vshr.u32        d24,d5,#19
+       add     r6,r6,r0,ror#2
+       eor     r12,r12,r8
+       vsli.32 d24,d5,#13
+       add     r5,r5,r2
+       eor     r2,r11,r4
+       veor    d25,d25,d24
+       eor     r0,r10,r10,ror#5
+       add     r6,r6,r12
+       vadd.i32        d6,d6,d25
+       and     r2,r2,r10
+       eor     r12,r0,r10,ror#19
+       vshr.u32        d24,d6,#17
+       eor     r0,r6,r6,ror#11
+       eor     r2,r2,r4
+       vsli.32 d24,d6,#15
+       add     r5,r5,r12,ror#6
+       eor     r12,r6,r7
+       vshr.u32        d25,d6,#10
+       eor     r0,r0,r6,ror#20
+       add     r5,r5,r2
+       veor    d25,d25,d24
+       ldr     r2,[sp,#60]
+       and     r3,r3,r12
+       vshr.u32        d24,d6,#19
+       add     r9,r9,r5
+       add     r5,r5,r0,ror#2
+       eor     r3,r3,r7
+       vld1.32 {q8},[r14,:128]!
+       add     r4,r4,r2
+       vsli.32 d24,d6,#13
+       eor     r2,r10,r11
+       eor     r0,r9,r9,ror#5
+       veor    d25,d25,d24
+       add     r5,r5,r3
+       and     r2,r2,r9
+       vadd.i32        d7,d7,d25
+       eor     r3,r0,r9,ror#19
+       eor     r0,r5,r5,ror#11
+       vadd.i32        q8,q8,q3
+       eor     r2,r2,r11
+       add     r4,r4,r3,ror#6
+       eor     r3,r5,r6
+       eor     r0,r0,r5,ror#20
+       add     r4,r4,r2
+       ldr     r2,[r14]
+       and     r12,r12,r3
+       add     r8,r8,r4
+       vst1.32 {q8},[r1,:128]!
+       add     r4,r4,r0,ror#2
+       eor     r12,r12,r6
+       teq     r2,#0                           @ check for K256 terminator
+       ldr     r2,[sp,#0]
+       sub     r1,r1,#64
+       bne     .L_00_48
+
+       ldr             r1,[sp,#68]
+       ldr             r0,[sp,#72]
+       sub             r14,r14,#256    @ rewind r14
+       teq             r1,r0
+       subeq           r1,r1,#64               @ avoid SEGV
+       vld1.8          {q0},[r1]!              @ load next input block
+       vld1.8          {q1},[r1]!
+       vld1.8          {q2},[r1]!
+       vld1.8          {q3},[r1]!
+       strne           r1,[sp,#68]
+       mov             r1,sp
+       add     r11,r11,r2
+       eor     r2,r9,r10
+       eor     r0,r8,r8,ror#5
+       add     r4,r4,r12
+       vld1.32 {q8},[r14,:128]!
+       and     r2,r2,r8
+       eor     r12,r0,r8,ror#19
+       eor     r0,r4,r4,ror#11
+       eor     r2,r2,r10
+       vrev32.8        q0,q0
+       add     r11,r11,r12,ror#6
+       eor     r12,r4,r5
+       eor     r0,r0,r4,ror#20
+       add     r11,r11,r2
+       vadd.i32        q8,q8,q0
+       ldr     r2,[sp,#4]
+       and     r3,r3,r12
+       add     r7,r7,r11
+       add     r11,r11,r0,ror#2
+       eor     r3,r3,r5
+       add     r10,r10,r2
+       eor     r2,r8,r9
+       eor     r0,r7,r7,ror#5
+       add     r11,r11,r3
+       and     r2,r2,r7
+       eor     r3,r0,r7,ror#19
+       eor     r0,r11,r11,ror#11
+       eor     r2,r2,r9
+       add     r10,r10,r3,ror#6
+       eor     r3,r11,r4
+       eor     r0,r0,r11,ror#20
+       add     r10,r10,r2
+       ldr     r2,[sp,#8]
+       and     r12,r12,r3
+       add     r6,r6,r10
+       add     r10,r10,r0,ror#2
+       eor     r12,r12,r4
+       add     r9,r9,r2
+       eor     r2,r7,r8
+       eor     r0,r6,r6,ror#5
+       add     r10,r10,r12
+       and     r2,r2,r6
+       eor     r12,r0,r6,ror#19
+       eor     r0,r10,r10,ror#11
+       eor     r2,r2,r8
+       add     r9,r9,r12,ror#6
+       eor     r12,r10,r11
+       eor     r0,r0,r10,ror#20
+       add     r9,r9,r2
+       ldr     r2,[sp,#12]
+       and     r3,r3,r12
+       add     r5,r5,r9
+       add     r9,r9,r0,ror#2
+       eor     r3,r3,r11
+       add     r8,r8,r2
+       eor     r2,r6,r7
+       eor     r0,r5,r5,ror#5
+       add     r9,r9,r3
+       and     r2,r2,r5
+       eor     r3,r0,r5,ror#19
+       eor     r0,r9,r9,ror#11
+       eor     r2,r2,r7
+       add     r8,r8,r3,ror#6
+       eor     r3,r9,r10
+       eor     r0,r0,r9,ror#20
+       add     r8,r8,r2
+       ldr     r2,[sp,#16]
+       and     r12,r12,r3
+       add     r4,r4,r8
+       add     r8,r8,r0,ror#2
+       eor     r12,r12,r10
+       vst1.32 {q8},[r1,:128]!
+       add     r7,r7,r2
+       eor     r2,r5,r6
+       eor     r0,r4,r4,ror#5
+       add     r8,r8,r12
+       vld1.32 {q8},[r14,:128]!
+       and     r2,r2,r4
+       eor     r12,r0,r4,ror#19
+       eor     r0,r8,r8,ror#11
+       eor     r2,r2,r6
+       vrev32.8        q1,q1
+       add     r7,r7,r12,ror#6
+       eor     r12,r8,r9
+       eor     r0,r0,r8,ror#20
+       add     r7,r7,r2
+       vadd.i32        q8,q8,q1
+       ldr     r2,[sp,#20]
+       and     r3,r3,r12
+       add     r11,r11,r7
+       add     r7,r7,r0,ror#2
+       eor     r3,r3,r9
+       add     r6,r6,r2
+       eor     r2,r4,r5
+       eor     r0,r11,r11,ror#5
+       add     r7,r7,r3
+       and     r2,r2,r11
+       eor     r3,r0,r11,ror#19
+       eor     r0,r7,r7,ror#11
+       eor     r2,r2,r5
+       add     r6,r6,r3,ror#6
+       eor     r3,r7,r8
+       eor     r0,r0,r7,ror#20
+       add     r6,r6,r2
+       ldr     r2,[sp,#24]
+       and     r12,r12,r3
+       add     r10,r10,r6
+       add     r6,r6,r0,ror#2
+       eor     r12,r12,r8
+       add     r5,r5,r2
+       eor     r2,r11,r4
+       eor     r0,r10,r10,ror#5
+       add     r6,r6,r12
+       and     r2,r2,r10
+       eor     r12,r0,r10,ror#19
+       eor     r0,r6,r6,ror#11
+       eor     r2,r2,r4
+       add     r5,r5,r12,ror#6
+       eor     r12,r6,r7
+       eor     r0,r0,r6,ror#20
+       add     r5,r5,r2
+       ldr     r2,[sp,#28]
+       and     r3,r3,r12
+       add     r9,r9,r5
+       add     r5,r5,r0,ror#2
+       eor     r3,r3,r7
+       add     r4,r4,r2
+       eor     r2,r10,r11
+       eor     r0,r9,r9,ror#5
+       add     r5,r5,r3
+       and     r2,r2,r9
+       eor     r3,r0,r9,ror#19
+       eor     r0,r5,r5,ror#11
+       eor     r2,r2,r11
+       add     r4,r4,r3,ror#6
+       eor     r3,r5,r6
+       eor     r0,r0,r5,ror#20
+       add     r4,r4,r2
+       ldr     r2,[sp,#32]
+       and     r12,r12,r3
+       add     r8,r8,r4
+       add     r4,r4,r0,ror#2
+       eor     r12,r12,r6
+       vst1.32 {q8},[r1,:128]!
+       add     r11,r11,r2
+       eor     r2,r9,r10
+       eor     r0,r8,r8,ror#5
+       add     r4,r4,r12
+       vld1.32 {q8},[r14,:128]!
+       and     r2,r2,r8
+       eor     r12,r0,r8,ror#19
+       eor     r0,r4,r4,ror#11
+       eor     r2,r2,r10
+       vrev32.8        q2,q2
+       add     r11,r11,r12,ror#6
+       eor     r12,r4,r5
+       eor     r0,r0,r4,ror#20
+       add     r11,r11,r2
+       vadd.i32        q8,q8,q2
+       ldr     r2,[sp,#36]
+       and     r3,r3,r12
+       add     r7,r7,r11
+       add     r11,r11,r0,ror#2
+       eor     r3,r3,r5
+       add     r10,r10,r2
+       eor     r2,r8,r9
+       eor     r0,r7,r7,ror#5
+       add     r11,r11,r3
+       and     r2,r2,r7
+       eor     r3,r0,r7,ror#19
+       eor     r0,r11,r11,ror#11
+       eor     r2,r2,r9
+       add     r10,r10,r3,ror#6
+       eor     r3,r11,r4
+       eor     r0,r0,r11,ror#20
+       add     r10,r10,r2
+       ldr     r2,[sp,#40]
+       and     r12,r12,r3
+       add     r6,r6,r10
+       add     r10,r10,r0,ror#2
+       eor     r12,r12,r4
+       add     r9,r9,r2
+       eor     r2,r7,r8
+       eor     r0,r6,r6,ror#5
+       add     r10,r10,r12
+       and     r2,r2,r6
+       eor     r12,r0,r6,ror#19
+       eor     r0,r10,r10,ror#11
+       eor     r2,r2,r8
+       add     r9,r9,r12,ror#6
+       eor     r12,r10,r11
+       eor     r0,r0,r10,ror#20
+       add     r9,r9,r2
+       ldr     r2,[sp,#44]
+       and     r3,r3,r12
+       add     r5,r5,r9
+       add     r9,r9,r0,ror#2
+       eor     r3,r3,r11
+       add     r8,r8,r2
+       eor     r2,r6,r7
+       eor     r0,r5,r5,ror#5
+       add     r9,r9,r3
+       and     r2,r2,r5
+       eor     r3,r0,r5,ror#19
+       eor     r0,r9,r9,ror#11
+       eor     r2,r2,r7
+       add     r8,r8,r3,ror#6
+       eor     r3,r9,r10
+       eor     r0,r0,r9,ror#20
+       add     r8,r8,r2
+       ldr     r2,[sp,#48]
+       and     r12,r12,r3
+       add     r4,r4,r8
+       add     r8,r8,r0,ror#2
+       eor     r12,r12,r10
+       vst1.32 {q8},[r1,:128]!
+       add     r7,r7,r2
+       eor     r2,r5,r6
+       eor     r0,r4,r4,ror#5
+       add     r8,r8,r12
+       vld1.32 {q8},[r14,:128]!
+       and     r2,r2,r4
+       eor     r12,r0,r4,ror#19
+       eor     r0,r8,r8,ror#11
+       eor     r2,r2,r6
+       vrev32.8        q3,q3
+       add     r7,r7,r12,ror#6
+       eor     r12,r8,r9
+       eor     r0,r0,r8,ror#20
+       add     r7,r7,r2
+       vadd.i32        q8,q8,q3
+       ldr     r2,[sp,#52]
+       and     r3,r3,r12
+       add     r11,r11,r7
+       add     r7,r7,r0,ror#2
+       eor     r3,r3,r9
+       add     r6,r6,r2
+       eor     r2,r4,r5
+       eor     r0,r11,r11,ror#5
+       add     r7,r7,r3
+       and     r2,r2,r11
+       eor     r3,r0,r11,ror#19
+       eor     r0,r7,r7,ror#11
+       eor     r2,r2,r5
+       add     r6,r6,r3,ror#6
+       eor     r3,r7,r8
+       eor     r0,r0,r7,ror#20
+       add     r6,r6,r2
+       ldr     r2,[sp,#56]
+       and     r12,r12,r3
+       add     r10,r10,r6
+       add     r6,r6,r0,ror#2
+       eor     r12,r12,r8
+       add     r5,r5,r2
+       eor     r2,r11,r4
+       eor     r0,r10,r10,ror#5
+       add     r6,r6,r12
+       and     r2,r2,r10
+       eor     r12,r0,r10,ror#19
+       eor     r0,r6,r6,ror#11
+       eor     r2,r2,r4
+       add     r5,r5,r12,ror#6
+       eor     r12,r6,r7
+       eor     r0,r0,r6,ror#20
+       add     r5,r5,r2
+       ldr     r2,[sp,#60]
+       and     r3,r3,r12
+       add     r9,r9,r5
+       add     r5,r5,r0,ror#2
+       eor     r3,r3,r7
+       add     r4,r4,r2
+       eor     r2,r10,r11
+       eor     r0,r9,r9,ror#5
+       add     r5,r5,r3
+       and     r2,r2,r9
+       eor     r3,r0,r9,ror#19
+       eor     r0,r5,r5,ror#11
+       eor     r2,r2,r11
+       add     r4,r4,r3,ror#6
+       eor     r3,r5,r6
+       eor     r0,r0,r5,ror#20
+       add     r4,r4,r2
+       ldr     r2,[sp,#64]
+       and     r12,r12,r3
+       add     r8,r8,r4
+       add     r4,r4,r0,ror#2
+       eor     r12,r12,r6
+       vst1.32 {q8},[r1,:128]!
+       ldr     r0,[r2,#0]
+       add     r4,r4,r12                       @ h+=Maj(a,b,c) from the past
+       ldr     r12,[r2,#4]
+       ldr     r3,[r2,#8]
+       ldr     r1,[r2,#12]
+       add     r4,r4,r0                        @ accumulate
+       ldr     r0,[r2,#16]
+       add     r5,r5,r12
+       ldr     r12,[r2,#20]
+       add     r6,r6,r3
+       ldr     r3,[r2,#24]
+       add     r7,r7,r1
+       ldr     r1,[r2,#28]
+       add     r8,r8,r0
+       str     r4,[r2],#4
+       add     r9,r9,r12
+       str     r5,[r2],#4
+       add     r10,r10,r3
+       str     r6,[r2],#4
+       add     r11,r11,r1
+       str     r7,[r2],#4
+       stmia   r2,{r8-r11}
+
+       movne   r1,sp
+       ldrne   r2,[sp,#0]
+       eorne   r12,r12,r12
+       ldreq   sp,[sp,#76]                     @ restore original sp
+       eorne   r3,r5,r6
+       bne     .L_00_48
+
+       ldmia   sp!,{r4-r12,pc}
+ENDPROC(sha256_transform_neon)
arch/arm/crypto/sha256_neon_glue.c new file +171 -0
new file mode 100644
index 0000000..698a498
@@ -0,0 +1,201 @@
+/*
+ * Glue code for the SHA256 Secure Hash Algorithm assembly implementation
+ * using NEON instructions.
+ *
+ * Copyright ? 2015 Google Inc.
+ *
+ * This file is based on sha512_neon_glue.c:
+ *   Copyright ? 2014 Jussi Kivilinna <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ */
+
+#include <crypto/internal/hash.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/cryptohash.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <crypto/sha.h>
+#include <asm/byteorder.h>
+#include <asm/simd.h>
+#include <asm/neon.h>
+
+asmlinkage void sha256_transform_neon(u32 *digest, const void *data,
+                                     unsigned int num_blks);
+
+
+static int sha256_neon_init(struct shash_desc *desc)
+{
+       struct sha256_state *sctx = shash_desc_ctx(desc);
+
+       sctx->state[0] = SHA256_H0;
+       sctx->state[1] = SHA256_H1;
+       sctx->state[2] = SHA256_H2;
+       sctx->state[3] = SHA256_H3;
+       sctx->state[4] = SHA256_H4;
+       sctx->state[5] = SHA256_H5;
+       sctx->state[6] = SHA256_H6;
+       sctx->state[7] = SHA256_H7;
+       sctx->count = 0;
+
+       return 0;
+}
+
+static int __sha256_neon_update(struct shash_desc *desc, const u8 *data,
+                               unsigned int len, unsigned int partial)
+{
+       struct sha256_state *sctx = shash_desc_ctx(desc);
+       unsigned int done = 0;
+
+       sctx->count += len;
+
+       if (partial) {
+               done = SHA256_BLOCK_SIZE - partial;
+               memcpy(sctx->buf + partial, data, done);
+               sha256_transform_neon(sctx->state, sctx->buf, 1);
+       }
+
+       if (len - done >= SHA256_BLOCK_SIZE) {
+               const unsigned int rounds = (len - done) / SHA256_BLOCK_SIZE;
+
+               sha256_transform_neon(sctx->state, data + done, rounds);
+               done += rounds * SHA256_BLOCK_SIZE;
+       }
+
+       memcpy(sctx->buf, data + done, len - done);
+
+       return 0;
+}
+
+static int sha256_neon_update(struct shash_desc *desc, const u8 *data,
+                            unsigned int len)
+{
+       struct sha256_state *sctx = shash_desc_ctx(desc);
+       unsigned int partial = sctx->count % SHA256_BLOCK_SIZE;
+       int res;
+
+       /* Handle the fast case right here */
+       if (partial + len < SHA256_BLOCK_SIZE) {
+               sctx->count += len;
+               memcpy(sctx->buf + partial, data, len);
+
+               return 0;
+       }
+
+       if (!may_use_simd()) {
+               res = crypto_sha256_update(desc, data, len);
+       } else {
+               kernel_neon_begin();
+               res = __sha256_neon_update(desc, data, len, partial);
+               kernel_neon_end();
+       }
+
+       return res;
+}
+
+/* Add padding and return the message digest. */
+static int sha256_neon_final(struct shash_desc *desc, u8 *out)
+{
+       struct sha256_state *sctx = shash_desc_ctx(desc);
+       unsigned int i, index, padlen;
+       __be32 *dst = (__be32 *)out;
+       __be64 bits;
+       static const u8 padding[SHA256_BLOCK_SIZE] = { 0x80, };
+
+       /* save number of bits */
+       bits = cpu_to_be64(sctx->count << 3);
+
+       /* Pad out to 56 mod 64 and append length */
+       index = sctx->count % SHA256_BLOCK_SIZE;
+       padlen = (index < 56) ? (56 - index) : ((SHA256_BLOCK_SIZE+56)-index);
+
+       if (!may_use_simd()) {
+               crypto_sha256_update(desc, padding, padlen);
+               crypto_sha256_update(desc, (const u8 *)&bits, sizeof(bits));
+       } else {
+               kernel_neon_begin();
+               /* We need to fill a whole block for __sha256_neon_update() */
+               if (padlen <= 56) {
+                       sctx->count += padlen;
+                       memcpy(sctx->buf + index, padding, padlen);
+               } else {
+                       __sha256_neon_update(desc, padding, padlen, index);
+               }
+               __sha256_neon_update(desc, (const u8 *)&bits,
+                                       sizeof(bits), 56);
+               kernel_neon_end();
+       }
+
+       /* Store state in digest */
+       for (i = 0; i < 8; i++)
+               dst[i] = cpu_to_be32(sctx->state[i]);
+
+       /* Wipe context */
+       memset(sctx, 0, sizeof(*sctx));
+
+       return 0;
+}
+
+static int sha256_neon_export(struct shash_desc *desc, void *out)
+{
+       struct sha256_state *sctx = shash_desc_ctx(desc);
+
+       memcpy(out, sctx, sizeof(*sctx));
+
+       return 0;
+}
+
+static int sha256_neon_import(struct shash_desc *desc, const void *in)
+{
+       struct sha256_state *sctx = shash_desc_ctx(desc);
+
+       memcpy(sctx, in, sizeof(*sctx));
+
+       return 0;
+}
+
+static struct shash_alg alg = {
+       .digestsize     =       SHA256_DIGEST_SIZE,
+       .init           =       sha256_neon_init,
+       .update         =       sha256_neon_update,
+       .final          =       sha256_neon_final,
+       .export         =       sha256_neon_export,
+       .import         =       sha256_neon_import,
+       .descsize       =       sizeof(struct sha256_state),
+       .statesize      =       sizeof(struct sha256_state),

arch/arm/crypto/sha256_neon_glue.c line 181

Quoted 10 lines
arch/arm/crypto/sha256_neon_glue.c new file +10 -0
+       .base           =       {
+               .cra_name       =       "sha256",
+               .cra_driver_name =      "sha256-neon",
+               .cra_priority   =       350,
+               .cra_flags      =       CRYPTO_ALG_TYPE_SHASH,
+               .cra_blocksize  =       SHA256_BLOCK_SIZE,
+               .cra_module     =       THIS_MODULE,
+       }
+};
+

You can also implement SHA-224 using the same core transform, it's just some trivial glue code.

Quoted 30 lines
arch/arm/crypto/sha256_neon_glue.c new file +20 -0
+static int __init sha256_neon_mod_init(void)
+{
+       if (!cpu_has_neon())
+               return -ENODEV;
+
+       return crypto_register_shash(&alg);
+}
+
+static void __exit sha256_neon_mod_fini(void)
+{
+       crypto_unregister_shash(&alg);
+}
+
+module_init(sha256_neon_mod_init);
+module_exit(sha256_neon_mod_fini);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("SHA256 Secure Hash Algorithm, NEON accelerated");
+
+MODULE_ALIAS("sha256");
crypto/Kconfig +2 -0
index 50f4da4..0505523 100644
@@ -610,6 +610,18 @@ config CRYPTO_SHA256
          This code also includes SHA-224, a 224 bit hash with 112 bits
          of security against collision attacks.
 
+config CRYPTO_SHA256_ARM_NEON
+       tristate "SHA256 digest algorithm (ARM NEON)"

crypto/Kconfig config CRYPTO_SHA256 · line 624

Quoted 10 lines
crypto/Kconfig +10 -0
+       depends on ARM && KERNEL_MODE_NEON && !CPU_BIG_ENDIAN
+       select CRYPTO_SHA256
+       select CRYPTO_HASH
+       help
+         SHA-256 secure hash standard (DFIPS 180-2) implemented
+         using ARM NEON instructions, when available.
+
+         This version of SHA implements a 256 bit hash with 128 bits of
+         security against collision attacks.
+

Could you please rebase this onto Herbert's cryptodev tree and move this to arch/arm/crypto/Kconfig?

crypto/Kconfig config CRYPTO_SHA256 · line 627

Quoted 3 lines
crypto/Kconfig +0 -0
 config CRYPTO_SHA256_SPARC64
        tristate "SHA224 and SHA256 digest algorithm (SPARC64)"
        depends on SPARC64

Regards,
Ard.

#2 lore raw

PATCH 1/1 arm: crypto: Add NEON optimized SHA-256

Quoted 1 line · Ard Biesheuvel

Have you tested this code with the tcrypt.ko module?

I have not, but I can look into it.

Quoted 2 lines

Did you talk to Andy about the license? I don't think this is permissible for the kernel as-is.

Unless I have misunderstood something, the license at the Cryptogams website includes an option to license the code under the GNU GPL.

However, I can certainly contact Andy to clarify his intentions.

Quoted 7 lines

This is broken on thumb-2, use adr instead

You can also implement SHA-224 using the same core transform, it's just some trivial glue code.

Could you please rebase this onto Herbert's cryptodev tree and move this to arch/arm/crypto/Kconfig?

Thanks for the comments, I will submit a second version once we have a clarification on the license.

Sami

#3 lore raw

PATCH 1/1 arm: crypto: Add NEON optimized SHA-256

Quoted 15 lines · Sami Tolvanen
Quoted 1 line · Ard Biesheuvel

Have you tested this code with the tcrypt.ko module?

I have not, but I can look into it.

Quoted 2 lines

Did you talk to Andy about the license? I don't think this is permissible for the kernel as-is.

Unless I have misunderstood something, the license at the Cryptogams website includes an option to license the code under the GNU GPL.

However, I can certainly contact Andy to clarify his intentions.

Quoted 1 line

This is broken on thumb-2, use adr instead

Quoted 9 lines
Quoted 5 lines

You can also implement SHA-224 using the same core transform, it's just some trivial glue code.

Could you please rebase this onto Herbert's cryptodev tree and move this to arch/arm/crypto/Kconfig?

Thanks for the comments, I will submit a second version once we have a clarification on the license.

I have tested your code with a Thumb2 kernel. With this patch folded, it builds and passes the tcrypt.ko test for me

arch/arm/crypto/sha256-armv7-neon.S +4 -5
@@ -10,7 +10,6 @@
 #include <linux/linkage.h>
 
 .text
-.code   32
 .fpu neon
 
 .type  K256,%object
@@ -44,15 +43,15 @@ ENTRY(sha256_transform_neon)
         *      %r1: data
         *      %r2: nblks
         */
-       sub     r3,pc,#8                @ sha256_transform_neon
        add     r2,r1,r2,lsl#6  @ len to point at the end of inp
 
        stmdb   sp!,{r4-r12,lr}
 
        mov     r12,sp
-       sub     sp,sp,#16*4+16          @ alloca
-       sub     r14,r3,#256+32  @ K256
-       bic     sp,sp,#15               @ align for 128-bit stores
+       sub     r14,sp,#16*4+16         @ alloca
+       bic     r14,r14,#15             @ align for 128-bit stores
+       mov     sp,r14
+       adr     r14,K256
 
        vld1.8          {q0},[r1]!
        vld1.8          {q1},[r1]!
#4 lore raw

PATCH 1/1 arm: crypto: Add NEON optimized SHA-256

Hi,

Quoted 11 lines
Quoted 11 lines
Quoted 1 line

Have you tested this code with the tcrypt.ko module?

I have not, but I can look into it.

Quoted 2 lines

Did you talk to Andy about the license? I don't think this is permissible for the kernel as-is.

Unless I have misunderstood something, the license at the Cryptogams website includes an option to license the code under the GNU GPL.

However, I can certainly contact Andy to clarify his intentions.

I have no problems with reusing assembly modules in kernel context. The whole idea behind cryptogams initiative was exactly to reuse code in different contexts. But I'd prefer if it's more of cooperative effort, when we help each other to improve code, test on and tune for more platforms single developer might have access to, cross-report problems, etc. For this reason I'd prefer if it can be arranged in way similar to bsaes-armv7 module, i.e. we work together on shared copy of module that generates assembly that can be then compiled for OpenSSL or kernel. Is it sensible? BTW, why stop at SHA256? There is SHA512 and NEON SHA1...

As for practicalities. In order to spare brain capacity for list subscribers, it would probably be appropriate to work out details such as naming of entry points in smaller group and present result when it's ready to go and tests. I'll start by looking at Thumb-ification...

Cheers.

#5 lore raw

PATCH 1/1 arm: crypto: Add NEON optimized SHA-256

Quoted 1 line · Andy Polyakov

I have no problems with reusing assembly modules in kernel context.

Awesome, thank you for clarifying this.

Quoted 3 lines

I'd prefer if it can be arranged in way similar to bsaes-armv7 module, i.e. we work together on shared copy of module that generates assembly that can be then compiled for OpenSSL or kernel. Is it sensible?

Sure, that sounds good to me.

Quoted 1 line

BTW, why stop at SHA256? There is SHA512 and NEON SHA1...

The kernel already has NEON SHA-1 and SHA-512, but for some reason is lacking SHA-256. I have not tested how they compare to yours though.

Sami

#6 lore raw

PATCH 1/1 arm: crypto: Add NEON optimized SHA-256

In reply to Andy Polyakov
Quoted 14 lines · Andy Polyakov

Hi,

Quoted 11 lines
Quoted 11 lines
Quoted 1 line

Have you tested this code with the tcrypt.ko module?

I have not, but I can look into it.

Quoted 2 lines

Did you talk to Andy about the license? I don't think this is permissible for the kernel as-is.

Unless I have misunderstood something, the license at the Cryptogams website includes an option to license the code under the GNU GPL.

However, I can certainly contact Andy to clarify his intentions.

Quoted 8 lines

I have no problems with reusing assembly modules in kernel context. The whole idea behind cryptogams initiative was exactly to reuse code in different contexts. But I'd prefer if it's more of cooperative effort, when we help each other to improve code, test on and tune for more platforms single developer might have access to, cross-report problems, etc. For this reason I'd prefer if it can be arranged in way similar to bsaes-armv7 module, i.e. we work together on shared copy of module that generates assembly that can be then compiled for OpenSSL or kernel. Is

Yes, that is what I thought.

@Sami, this also means we should integrate the .pl file and the generated .S. Please have a look at how I integrated Andy's bsaes-armv7.pl module.

Quoted 7 lines

it sensible? BTW, why stop at SHA256? There is SHA512 and NEON SHA1...

As for practicalities. In order to spare brain capacity for list subscribers, it would probably be appropriate to work out details such as naming of entry points in smaller group and present result when it's ready to go and tests. I'll start by looking at Thumb-ification...

@Andy: the core code builds without problems, but for Thumb2 there are some trivial changes to apply:
- '.code 32' needs to be made conditional
- use adr instead of pc arithmetic for the address of K256
- bic cannot use r13 as input/output, so it needs to go via another register
- some conditional instructions need 'it' instructions added (not strictly necessary for the kernel, because it passes -mimplicit-it-thumb on the assembler command line, but nice for completeness)
(see patch in other reply)

I am happy to test and/or review stuff as well.

Thanks,
Ard.

#7 lore raw

PATCH v2 1/1 arm: crypto: Add optimized SHA-256/224

In reply to Sami Tolvanen

Add Andy Polyakov's optimized assembly and NEON implementations for SHA-256/224.

The sha256-armv4.pl script for generating the assembly code is from OpenSSL commit 2ecd32a1f8f0643ae7b38f59bbaf9f0d6ef326fe.

Compared to sha256-generic these implementations have the following tcrypt speed improvements on Motorola Nexus 6 (Snapdragon 805):

  bs    b/u      sha256-neon  sha256-asm
  16    16       x1.32        x1.19
  64    16       x1.27        x1.15
  64    64       x1.36        x1.20
  256   16       x1.22        x1.11
  256   64       x1.36        x1.19
  256   256      x1.59        x1.23
  1024  16       x1.21        x1.10
  1024  256      x1.65        x1.23
  1024  1024     x1.76        x1.25
  2048  16       x1.21        x1.10
  2048  256      x1.66        x1.23
  2048  1024     x1.78        x1.25
  2048  2048     x1.79        x1.25
  4096  16       x1.20        x1.09
  4096  256      x1.66        x1.23
  4096  1024     x1.79        x1.26
  4096  4096     x1.82        x1.26
  8192  16       x1.20        x1.09
  8192  256      x1.67        x1.23
  8192  1024     x1.80        x1.26
  8192  4096     x1.85        x1.28
  8192  8192     x1.85        x1.27

Where bs refers to block size and b/u to bytes per update.

---
Changes since v1:
Rebased to Herbert's cryptodev tree
Include sha256-armv4.pl and use it to generate sha256-core.S Add integer-only assembly version as sha256-asm Add support for SHA-224 to the glue code
Change priority for sha256/224-ce to 300

---
 arch/arm/crypto/Kconfig               |    7 
 arch/arm/crypto/Makefile              |    8 
 arch/arm/crypto/sha2-ce-glue.c        |    4 
 arch/arm/crypto/sha256-armv4.pl       |  713 ++++++
 arch/arm/crypto/sha256-core.S_shipped | 2775 ++++++++++++++++++++++++
 arch/arm/crypto/sha256_glue.c         |  246 ++
 arch/arm/crypto/sha256_glue.h         |   23 
 arch/arm/crypto/sha256_neon_glue.c    |  172 +
 8 files changed, 3945 insertions(+), 3 deletions(-)
arch/arm/crypto/Kconfig +7 -0
index d63f319..458729d 100644
@@ -46,6 +46,13 @@ config CRYPTO_SHA2_ARM_CE
 	  SHA-256 secure hash standard (DFIPS 180-2) implemented
 	  using special ARMv8 Crypto Extensions.
 
+config CRYPTO_SHA256_ARM
+	tristate "SHA-224/256 digest algorithm (ARM-asm and NEON)"
+	select CRYPTO_HASH
+	help
+	  SHA-256 secure hash standard (DFIPS 180-2) implemented
+	  using optimized ARM assembler and NEON, when available.
+
 config CRYPTO_SHA512_ARM_NEON
 	tristate "SHA384 and SHA512 digest algorithm (ARM NEON)"
 	depends on KERNEL_MODE_NEON
arch/arm/crypto/Makefile +7 -1
index 9a273bd..ef46e89 100644
@@ -7,6 +7,7 @@ obj-$(CONFIG_CRYPTO_AES_ARM_BS) += aes-arm-bs.o
 obj-$(CONFIG_CRYPTO_AES_ARM_CE) += aes-arm-ce.o
 obj-$(CONFIG_CRYPTO_SHA1_ARM) += sha1-arm.o
 obj-$(CONFIG_CRYPTO_SHA1_ARM_NEON) += sha1-arm-neon.o
+obj-$(CONFIG_CRYPTO_SHA256_ARM) += sha256-arm.o
 obj-$(CONFIG_CRYPTO_SHA512_ARM_NEON) += sha512-arm-neon.o
 obj-$(CONFIG_CRYPTO_SHA1_ARM_CE) += sha1-arm-ce.o
 obj-$(CONFIG_CRYPTO_SHA2_ARM_CE) += sha2-arm-ce.o
@@ -16,6 +17,8 @@ aes-arm-y	:= aes-armv4.o aes_glue.o
 aes-arm-bs-y	:= aesbs-core.o aesbs-glue.o
 sha1-arm-y	:= sha1-armv4-large.o sha1_glue.o
 sha1-arm-neon-y	:= sha1-armv7-neon.o sha1_neon_glue.o
+sha256-arm-neon-$(CONFIG_KERNEL_MODE_NEON) := sha256_neon_glue.o
+sha256-arm-y	:= sha256-core.o sha256_glue.o $(sha256-arm-neon-y)
 sha512-arm-neon-y := sha512-armv7-neon.o sha512_neon_glue.o
 sha1-arm-ce-y	:= sha1-ce-core.o sha1-ce-glue.o
 sha2-arm-ce-y	:= sha2-ce-core.o sha2-ce-glue.o
@@ -28,4 +31,7 @@ quiet_cmd_perl = PERL    $@
 $(src)/aesbs-core.S_shipped: $(src)/bsaes-armv7.pl
 	$(call cmd,perl)
 
-.PRECIOUS: $(obj)/aesbs-core.S
+$(src)/sha256-core.S_shipped: $(src)/sha256-armv4.pl
+	$(call cmd,perl)
+
+.PRECIOUS: $(obj)/aesbs-core.S $(obj)/sha256-core.S
arch/arm/crypto/sha2-ce-glue.c +2 -2
index 9ffe8ad..0449eca 100644
@@ -163,7 +163,7 @@ static struct shash_alg algs[] = { {
 	.base			= {
 		.cra_name		= "sha224",
 		.cra_driver_name	= "sha224-ce",
-		.cra_priority		= 200,
+		.cra_priority		= 300,
 		.cra_flags		= CRYPTO_ALG_TYPE_SHASH,
 		.cra_blocksize		= SHA256_BLOCK_SIZE,
 		.cra_module		= THIS_MODULE,
@@ -180,7 +180,7 @@ static struct shash_alg algs[] = { {
 	.base			= {
 		.cra_name		= "sha256",
 		.cra_driver_name	= "sha256-ce",
-		.cra_priority		= 200,
+		.cra_priority		= 300,
 		.cra_flags		= CRYPTO_ALG_TYPE_SHASH,
 		.cra_blocksize		= SHA256_BLOCK_SIZE,
 		.cra_module		= THIS_MODULE,
arch/arm/crypto/sha256-armv4.pl new file +713 -0

713 lines not on this page · raw message

arch/arm/crypto/sha256-core.S_shipped new file +2775 -0

2,235 lines not on this page · raw message

arch/arm/crypto/sha256_glue.c new file +246 -0

246 lines not on this page · raw message

arch/arm/crypto/sha256_glue.h new file +23 -0
new file mode 100644
index 0000000..0312f4f

Lines of this file are not shown. View the raw message.

arch/arm/crypto/sha256_neon_glue.c new file +172 -0

172 lines not on this page · raw message

The rest of this diff is not shown. View the raw message.

Part of the diff is not shown here. View the raw message.

#8 lore raw

PATCH v2 1/1 arm: crypto: Add optimized SHA-256/224

(resending due to size bounce)

Quoted 33 lines · Sami Tolvanen

Add Andy Polyakov's optimized assembly and NEON implementations for SHA-256/224.

The sha256-armv4.pl script for generating the assembly code is from OpenSSL commit 2ecd32a1f8f0643ae7b38f59bbaf9f0d6ef326fe.

Compared to sha256-generic these implementations have the following tcrypt speed improvements on Motorola Nexus 6 (Snapdragon 805):

  bs    b/u      sha256-neon  sha256-asm
  16    16       x1.32        x1.19
  64    16       x1.27        x1.15
  64    64       x1.36        x1.20
  256   16       x1.22        x1.11
  256   64       x1.36        x1.19
  256   256      x1.59        x1.23
  1024  16       x1.21        x1.10
  1024  256      x1.65        x1.23
  1024  1024     x1.76        x1.25
  2048  16       x1.21        x1.10
  2048  256      x1.66        x1.23
  2048  1024     x1.78        x1.25
  2048  2048     x1.79        x1.25
  4096  16       x1.20        x1.09
  4096  256      x1.66        x1.23
  4096  1024     x1.79        x1.26
  4096  4096     x1.82        x1.26
  8192  16       x1.20        x1.09
  8192  256      x1.67        x1.23
  8192  1024     x1.80        x1.26
  8192  4096     x1.85        x1.28
  8192  8192     x1.85        x1.27
Quoted 5 lines

Where bs refers to block size and b/u to bytes per update.

This builds fine and passes the tcrypt.ko tests in ARM and Thumb2 and even in big-endian (ARM) mode, so

Nice work!

Ard.

Quoted 19 lines

---
Changes since v1:
Rebased to Herbert's cryptodev tree
Include sha256-armv4.pl and use it to generate sha256-core.S Add integer-only assembly version as sha256-asm Add support for SHA-224 to the glue code
Change priority for sha256/224-ce to 300

---
 arch/arm/crypto/Kconfig               |    7
 arch/arm/crypto/Makefile              |    8
 arch/arm/crypto/sha2-ce-glue.c        |    4
 arch/arm/crypto/sha256-armv4.pl       |  713 ++++++
 arch/arm/crypto/sha256-core.S_shipped | 2775 ++++++++++++++++++++++++
 arch/arm/crypto/sha256_glue.c         |  246 ++
 arch/arm/crypto/sha256_glue.h         |   23
 arch/arm/crypto/sha256_neon_glue.c    |  172 +
 8 files changed, 3945 insertions(+), 3 deletions(-)
maintainer
#9 lore raw

PATCH v2 1/1 arm: crypto: Add optimized SHA-256/224

Quoted 1 line · Ard Biesheuvel

(resending due to size bounce)

Aha that's why the patch didn't make it through. Can it be split up?

Thanks,

Signature · 3 lines
Email: Herbert Xu <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
#10 lore raw

PATCH v2 1/1 arm: crypto: Add optimized SHA-256/224

Quoted 5 lines · Herbert Xu
Quoted 1 line · Ard Biesheuvel

(resending due to size bounce)

Aha that's why the patch didn't make it through. Can it be split up?

Not so easily. It consists (among other things) of a .pl file that generates a .S file, but to prevent introducing a build time dependency on perl, the .S file is included as a .S_shipped file. That is the big one.

i suppose we could add the .S_shipped file in a separate patch, but I'd prefer to keep it as is

maintainer
#11 lore raw

PATCH v2 1/1 arm: crypto: Add optimized SHA-256/224

Quoted 8 lines · Ard Biesheuvel

Not so easily. It consists (among other things) of a .pl file that generates a .S file, but to prevent introducing a build time dependency on perl, the .S file is included as a .S_shipped file. That is the big one.

i suppose we could add the .S_shipped file in a separate patch, but I'd prefer to keep it as is

OK then this will have to go up on a website somewhere and then the URL can be posted to the list for review.

Thanks,

Signature · 3 lines
Email: Herbert Xu <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
#12 lore raw

PATCH v2 1/1 arm: crypto: Add optimized SHA-256/224

Quoted 7 lines · Herbert Xu
Quoted 6 lines · Ard Biesheuvel

Not so easily. It consists (among other things) of a .pl file that generates a .S file, but to prevent introducing a build time dependency on perl, the .S file is included as a .S_shipped file. That is the big one.

Quoted 6 lines
Quoted 2 lines

i suppose we could add the .S_shipped file in a separate patch, but I'd prefer to keep it as is

OK then this will have to go up on a website somewhere and then the URL can be posted to the list for review.

You can pull it from here if you like
https://git.linaro.org/people/ard.biesheuvel/linux-arm.git/shortlog/refs/tags/arm-sha256-neon
(rebased onto your cryptodev-2.6/master branch as of 30 mins ago)

Does that work or you?

Thanks,
Ard.

maintainer
#13 lore raw

PATCH v2 1/1 arm: crypto: Add optimized SHA-256/224

In reply to Sami Tolvanen
Quoted 33 lines · Sami Tolvanen

Add Andy Polyakov's optimized assembly and NEON implementations for SHA-256/224.

The sha256-armv4.pl script for generating the assembly code is from OpenSSL commit 2ecd32a1f8f0643ae7b38f59bbaf9f0d6ef326fe.

Compared to sha256-generic these implementations have the following tcrypt speed improvements on Motorola Nexus 6 (Snapdragon 805):

  bs    b/u      sha256-neon  sha256-asm
  16    16       x1.32        x1.19
  64    16       x1.27        x1.15
  64    64       x1.36        x1.20
  256   16       x1.22        x1.11
  256   64       x1.36        x1.19
  256   256      x1.59        x1.23
  1024  16       x1.21        x1.10
  1024  256      x1.65        x1.23
  1024  1024     x1.76        x1.25
  2048  16       x1.21        x1.10
  2048  256      x1.66        x1.23
  2048  1024     x1.78        x1.25
  2048  2048     x1.79        x1.25
  4096  16       x1.20        x1.09
  4096  256      x1.66        x1.23
  4096  1024     x1.79        x1.26
  4096  4096     x1.82        x1.26
  8192  16       x1.20        x1.09
  8192  256      x1.67        x1.23
  8192  1024     x1.80        x1.26
  8192  4096     x1.85        x1.28
  8192  8192     x1.85        x1.27
Quoted 4 lines

Where bs refers to block size and b/u to bytes per update.

Your patch didn't make it to the linux-crypto list and therefore it never got into patchwork. Can you please find out why and resend it?

Thanks,

Signature · 3 lines
Email: Herbert Xu <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
#14 lore raw

PATCH v2 1/1 arm: crypto: Add optimized SHA-256/224

Quoted 34 lines · Herbert Xu
Quoted 33 lines · Sami Tolvanen

Add Andy Polyakov's optimized assembly and NEON implementations for SHA-256/224.

The sha256-armv4.pl script for generating the assembly code is from OpenSSL commit 2ecd32a1f8f0643ae7b38f59bbaf9f0d6ef326fe.

Compared to sha256-generic these implementations have the following tcrypt speed improvements on Motorola Nexus 6 (Snapdragon 805):

  bs    b/u      sha256-neon  sha256-asm
  16    16       x1.32        x1.19
  64    16       x1.27        x1.15
  64    64       x1.36        x1.20
  256   16       x1.22        x1.11
  256   64       x1.36        x1.19
  256   256      x1.59        x1.23
  1024  16       x1.21        x1.10
  1024  256      x1.65        x1.23
  1024  1024     x1.76        x1.25
  2048  16       x1.21        x1.10
  2048  256      x1.66        x1.23
  2048  1024     x1.78        x1.25
  2048  2048     x1.79        x1.25
  4096  16       x1.20        x1.09
  4096  256      x1.66        x1.23
  4096  1024     x1.79        x1.26
  4096  4096     x1.82        x1.26
  8192  16       x1.20        x1.09
  8192  256      x1.67        x1.23
  8192  1024     x1.80        x1.26
  8192  4096     x1.85        x1.28
  8192  8192     x1.85        x1.27
Quoted 9 lines
Quoted 4 lines

Where bs refers to block size and b/u to bytes per update.

Your patch didn't make it to the linux-crypto list and therefore it never got into patchwork. Can you please find out why and resend it?

Most likely because it is so big ...

#15 lore raw

PATCH v2 1/1 arm: crypto: Add optimized SHA-256/224

In reply to Sami Tolvanen
Quoted 283 lines · Sami Tolvanen

Add Andy Polyakov's optimized assembly and NEON implementations for SHA-256/224.

The sha256-armv4.pl script for generating the assembly code is from OpenSSL commit 2ecd32a1f8f0643ae7b38f59bbaf9f0d6ef326fe.

Compared to sha256-generic these implementations have the following tcrypt speed improvements on Motorola Nexus 6 (Snapdragon 805):

  bs    b/u      sha256-neon  sha256-asm
  16    16       x1.32        x1.19
  64    16       x1.27        x1.15
  64    64       x1.36        x1.20
  256   16       x1.22        x1.11
  256   64       x1.36        x1.19
  256   256      x1.59        x1.23
  1024  16       x1.21        x1.10
  1024  256      x1.65        x1.23
  1024  1024     x1.76        x1.25
  2048  16       x1.21        x1.10
  2048  256      x1.66        x1.23
  2048  1024     x1.78        x1.25
  2048  2048     x1.79        x1.25
  4096  16       x1.20        x1.09
  4096  256      x1.66        x1.23
  4096  1024     x1.79        x1.26
  4096  4096     x1.82        x1.26
  8192  16       x1.20        x1.09
  8192  256      x1.67        x1.23
  8192  1024     x1.80        x1.26
  8192  4096     x1.85        x1.28
  8192  8192     x1.85        x1.27

Where bs refers to block size and b/u to bytes per update.

---
Changes since v1:
Rebased to Herbert's cryptodev tree
Include sha256-armv4.pl and use it to generate sha256-core.S Add integer-only assembly version as sha256-asm Add support for SHA-224 to the glue code
Change priority for sha256/224-ce to 300

---
 arch/arm/crypto/Kconfig               |    7 
 arch/arm/crypto/Makefile              |    8 
 arch/arm/crypto/sha2-ce-glue.c        |    4 
 arch/arm/crypto/sha256-armv4.pl       |  713 ++++++
 arch/arm/crypto/sha256-core.S_shipped | 2775 ++++++++++++++++++++++++
 arch/arm/crypto/sha256_glue.c         |  246 ++
 arch/arm/crypto/sha256_glue.h         |   23 
 arch/arm/crypto/sha256_neon_glue.c    |  172 +
 8 files changed, 3945 insertions(+), 3 deletions(-)
arch/arm/crypto/Kconfig +7 -0
index d63f319..458729d 100644
@@ -46,6 +46,13 @@ config CRYPTO_SHA2_ARM_CE
 	  SHA-256 secure hash standard (DFIPS 180-2) implemented
 	  using special ARMv8 Crypto Extensions.
 
+config CRYPTO_SHA256_ARM
+	tristate "SHA-224/256 digest algorithm (ARM-asm and NEON)"
+	select CRYPTO_HASH
+	help
+	  SHA-256 secure hash standard (DFIPS 180-2) implemented
+	  using optimized ARM assembler and NEON, when available.
+
 config CRYPTO_SHA512_ARM_NEON
 	tristate "SHA384 and SHA512 digest algorithm (ARM NEON)"
 	depends on KERNEL_MODE_NEON
arch/arm/crypto/Makefile +7 -1
index 9a273bd..ef46e89 100644
@@ -7,6 +7,7 @@ obj-$(CONFIG_CRYPTO_AES_ARM_BS) += aes-arm-bs.o
 obj-$(CONFIG_CRYPTO_AES_ARM_CE) += aes-arm-ce.o
 obj-$(CONFIG_CRYPTO_SHA1_ARM) += sha1-arm.o
 obj-$(CONFIG_CRYPTO_SHA1_ARM_NEON) += sha1-arm-neon.o
+obj-$(CONFIG_CRYPTO_SHA256_ARM) += sha256-arm.o
 obj-$(CONFIG_CRYPTO_SHA512_ARM_NEON) += sha512-arm-neon.o
 obj-$(CONFIG_CRYPTO_SHA1_ARM_CE) += sha1-arm-ce.o
 obj-$(CONFIG_CRYPTO_SHA2_ARM_CE) += sha2-arm-ce.o
@@ -16,6 +17,8 @@ aes-arm-y	:= aes-armv4.o aes_glue.o
 aes-arm-bs-y	:= aesbs-core.o aesbs-glue.o
 sha1-arm-y	:= sha1-armv4-large.o sha1_glue.o
 sha1-arm-neon-y	:= sha1-armv7-neon.o sha1_neon_glue.o
+sha256-arm-neon-$(CONFIG_KERNEL_MODE_NEON) := sha256_neon_glue.o
+sha256-arm-y	:= sha256-core.o sha256_glue.o $(sha256-arm-neon-y)
 sha512-arm-neon-y := sha512-armv7-neon.o sha512_neon_glue.o
 sha1-arm-ce-y	:= sha1-ce-core.o sha1-ce-glue.o
 sha2-arm-ce-y	:= sha2-ce-core.o sha2-ce-glue.o
@@ -28,4 +31,7 @@ quiet_cmd_perl = PERL    $@
 $(src)/aesbs-core.S_shipped: $(src)/bsaes-armv7.pl
 	$(call cmd,perl)
 
-.PRECIOUS: $(obj)/aesbs-core.S
+$(src)/sha256-core.S_shipped: $(src)/sha256-armv4.pl
+	$(call cmd,perl)
+
+.PRECIOUS: $(obj)/aesbs-core.S $(obj)/sha256-core.S
arch/arm/crypto/sha2-ce-glue.c +2 -2
index 9ffe8ad..0449eca 100644
@@ -163,7 +163,7 @@ static struct shash_alg algs[] = { {
 	.base			= {
 		.cra_name		= "sha224",
 		.cra_driver_name	= "sha224-ce",
-		.cra_priority		= 200,
+		.cra_priority		= 300,
 		.cra_flags		= CRYPTO_ALG_TYPE_SHASH,
 		.cra_blocksize		= SHA256_BLOCK_SIZE,
 		.cra_module		= THIS_MODULE,
@@ -180,7 +180,7 @@ static struct shash_alg algs[] = { {
 	.base			= {
 		.cra_name		= "sha256",
 		.cra_driver_name	= "sha256-ce",
-		.cra_priority		= 200,
+		.cra_priority		= 300,
 		.cra_flags		= CRYPTO_ALG_TYPE_SHASH,
 		.cra_blocksize		= SHA256_BLOCK_SIZE,
 		.cra_module		= THIS_MODULE,
arch/arm/crypto/sha256-armv4.pl new file +150 -0
new file mode 100644
index 0000000..4fee74d
@@ -0,0 +1,713 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Written by Andy Polyakov <[email protected]> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+#
+# Permission to use under GPL terms is granted.
+# ====================================================================
+
+# SHA256 block procedure for ARMv4. May 2007.
+
+# Performance is ~2x better than gcc 3.4 generated code and in "abso-
+# lute" terms is ~2250 cycles per 64-byte block or ~35 cycles per
+# byte [on single-issue Xscale PXA250 core].
+
+# July 2010.
+#
+# Rescheduling for dual-issue pipeline resulted in 22% improvement on
+# Cortex A8 core and ~20 cycles per processed byte.
+
+# February 2011.
+#
+# Profiler-assisted and platform-specific optimization resulted in 16%
+# improvement on Cortex A8 core and ~15.4 cycles per processed byte.
+
+# September 2013.
+#
+# Add NEON implementation. On Cortex A8 it was measured to process one
+# byte in 12.5 cycles or 23% faster than integer-only code. Snapdragon
+# S4 does it in 12.5 cycles too, but it's 50% faster than integer-only
+# code (meaning that latter performs sub-optimally, nothing was done
+# about it).
+
+# May 2014.
+#
+# Add ARMv8 code path performing at 2.0 cpb on Apple A7.
+
+while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {}
+open STDOUT,">$output";
+
+$ctx="r0";	$t0="r0";
+$inp="r1";	$t4="r1";
+$len="r2";	$t1="r2";
+$T1="r3";	$t3="r3";
+$A="r4";
+$B="r5";
+$C="r6";
+$D="r7";
+$E="r8";
+$F="r9";
+$G="r10";
+$H="r11";
+ at V=($A,$B,$C,$D,$E,$F,$G,$H);
+$t2="r12";
+$Ktbl="r14";
+
+ at Sigma0=( 2,13,22);
+ at Sigma1=( 6,11,25);
+ at sigma0=( 7,18, 3);
+ at sigma1=(17,19,10);
+
+sub BODY_00_15 {
+my ($i,$a,$b,$c,$d,$e,$f,$g,$h) = @_;
+
+$code.=<<___ if ($i<16);
+#if __ARM_ARCH__>=7
+	@ ldr	$t1,[$inp],#4			@ $i
+# if $i==15
+	str	$inp,[sp,#17*4]			@ make room for $t4
+# endif
+	eor	$t0,$e,$e,ror#`$Sigma1[1]-$Sigma1[0]`
+	add	$a,$a,$t2			@ h+=Maj(a,b,c) from the past
+	eor	$t0,$t0,$e,ror#`$Sigma1[2]-$Sigma1[0]`	@ Sigma1(e)
+	rev	$t1,$t1
+#else
+	@ ldrb	$t1,[$inp,#3]			@ $i
+	add	$a,$a,$t2			@ h+=Maj(a,b,c) from the past
+	ldrb	$t2,[$inp,#2]
+	ldrb	$t0,[$inp,#1]
+	orr	$t1,$t1,$t2,lsl#8
+	ldrb	$t2,[$inp],#4
+	orr	$t1,$t1,$t0,lsl#16
+# if $i==15
+	str	$inp,[sp,#17*4]			@ make room for $t4
+# endif
+	eor	$t0,$e,$e,ror#`$Sigma1[1]-$Sigma1[0]`
+	orr	$t1,$t1,$t2,lsl#24
+	eor	$t0,$t0,$e,ror#`$Sigma1[2]-$Sigma1[0]`	@ Sigma1(e)
+#endif
+___
+$code.=<<___;
+	ldr	$t2,[$Ktbl],#4			@ *K256++
+	add	$h,$h,$t1			@ h+=X[i]
+	str	$t1,[sp,#`$i%16`*4]
+	eor	$t1,$f,$g
+	add	$h,$h,$t0,ror#$Sigma1[0]	@ h+=Sigma1(e)
+	and	$t1,$t1,$e
+	add	$h,$h,$t2			@ h+=K256[i]
+	eor	$t1,$t1,$g			@ Ch(e,f,g)
+	eor	$t0,$a,$a,ror#`$Sigma0[1]-$Sigma0[0]`
+	add	$h,$h,$t1			@ h+=Ch(e,f,g)
+#if $i==31
+	and	$t2,$t2,#0xff
+	cmp	$t2,#0xf2			@ done?
+#endif
+#if $i<15
+# if __ARM_ARCH__>=7
+	ldr	$t1,[$inp],#4			@ prefetch
+# else
+	ldrb	$t1,[$inp,#3]
+# endif
+	eor	$t2,$a,$b			@ a^b, b^c in next round
+#else
+	ldr	$t1,[sp,#`($i+2)%16`*4]		@ from future BODY_16_xx
+	eor	$t2,$a,$b			@ a^b, b^c in next round
+	ldr	$t4,[sp,#`($i+15)%16`*4]	@ from future BODY_16_xx
+#endif
+	eor	$t0,$t0,$a,ror#`$Sigma0[2]-$Sigma0[0]`	@ Sigma0(a)
+	and	$t3,$t3,$t2			@ (b^c)&=(a^b)
+	add	$d,$d,$h			@ d+=h
+	eor	$t3,$t3,$b			@ Maj(a,b,c)
+	add	$h,$h,$t0,ror#$Sigma0[0]	@ h+=Sigma0(a)
+	@ add	$h,$h,$t3			@ h+=Maj(a,b,c)
+___
+	($t2,$t3)=($t3,$t2);
+}
+
+sub BODY_16_XX {
+my ($i,$a,$b,$c,$d,$e,$f,$g,$h) = @_;
+
+$code.=<<___;
+	@ ldr	$t1,[sp,#`($i+1)%16`*4]		@ $i
+	@ ldr	$t4,[sp,#`($i+14)%16`*4]
+	mov	$t0,$t1,ror#$sigma0[0]
+	add	$a,$a,$t2			@ h+=Maj(a,b,c) from the past
+	mov	$t2,$t4,ror#$sigma1[0]
+	eor	$t0,$t0,$t1,ror#$sigma0[1]
+	eor	$t2,$t2,$t4,ror#$sigma1[1]
+	eor	$t0,$t0,$t1,lsr#$sigma0[2]	@ sigma0(X[i+1])
+	ldr	$t1,[sp,#`($i+0)%16`*4]
+	eor	$t2,$t2,$t4,lsr#$sigma1[2]	@ sigma1(X[i+14])
+	ldr	$t4,[sp,#`($i+9)%16`*4]
+
+	add	$t2,$t2,$t0
+	eor	$t0,$e,$e,ror#`$Sigma1[1]-$Sigma1[0]`	@ from BODY_00_15
+	add	$t1,$t1,$t2
+	eor	$t0,$t0,$e,ror#`$Sigma1[2]-$Sigma1[0]`	@ Sigma1(e)
+	add	$t1,$t1,$t4			@ X[i]

arch/arm/crypto/sha256-armv4.pl line 160

Quoted 10 lines
arch/arm/crypto/sha256-armv4.pl new file +10 -0
+___
+	&BODY_00_15(@_);
+}
+
+$code=<<___;
+#ifndef __KERNEL__
+# include "arm_arch.h"
+#else
+# define __ARM_ARCH__ __LINUX_ARM_ARCH__
+# define __ARM_MAX_ARCH__ 7

I'm not sure this will work for kernel that is for older arm

Quoted 281 lines
arch/arm/crypto/sha256-armv4.pl new file +281 -0
+#endif
+
+.text
+#if __ARM_ARCH__<7
+.code	32
+#else
+.syntax unified
+# ifdef __thumb2__
+.thumb
+# else
+.code   32
+# endif
+#endif
+
+.type	K256,%object
+.align	5
+K256:
+.word	0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5
+.word	0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5
+.word	0xd807aa98,0x12835b01,0x243185be,0x550c7dc3
+.word	0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174
+.word	0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc
+.word	0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da
+.word	0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7
+.word	0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967
+.word	0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13
+.word	0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85
+.word	0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3
+.word	0xd192e819,0xd6990624,0xf40e3585,0x106aa070
+.word	0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5
+.word	0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3
+.word	0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208
+.word	0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
+.size	K256,.-K256
+.word	0				@ terminator
+#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__)
+.LOPENSSL_armcap:
+.word	OPENSSL_armcap_P-sha256_block_data_order
+#endif
+.align	5
+
+.global	sha256_block_data_order
+.type	sha256_block_data_order,%function
+sha256_block_data_order:
+#if __ARM_ARCH__<7
+	sub	r3,pc,#8		@ sha256_block_data_order
+#else
+	adr	r3,sha256_block_data_order
+#endif
+#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__)
+	ldr	r12,.LOPENSSL_armcap
+	ldr	r12,[r3,r12]		@ OPENSSL_armcap_P
+	tst	r12,#ARMV8_SHA256
+	bne	.LARMv8
+	tst	r12,#ARMV7_NEON
+	bne	.LNEON
+#endif
+	add	$len,$inp,$len,lsl#6	@ len to point at the end of inp
+	stmdb	sp!,{$ctx,$inp,$len,r4-r11,lr}
+	ldmia	$ctx,{$A,$B,$C,$D,$E,$F,$G,$H}
+	sub	$Ktbl,r3,#256+32	@ K256
+	sub	sp,sp,#16*4		@ alloca(X[16])
+.Loop:
+# if __ARM_ARCH__>=7
+	ldr	$t1,[$inp],#4
+# else
+	ldrb	$t1,[$inp,#3]
+# endif
+	eor	$t3,$B,$C		@ magic
+	eor	$t2,$t2,$t2
+___
+for($i=0;$i<16;$i++)	{ &BODY_00_15($i,@V); unshift(@V,pop(@V)); }
+$code.=".Lrounds_16_xx:\n";
+for (;$i<32;$i++)	{ &BODY_16_XX($i,@V); unshift(@V,pop(@V)); }
+$code.=<<___;
+#if __ARM_ARCH__>=7
+	ite	eq			@ Thumb2 thing, sanity check in ARM
+#endif
+	ldreq	$t3,[sp,#16*4]		@ pull ctx
+	bne	.Lrounds_16_xx
+
+	add	$A,$A,$t2		@ h+=Maj(a,b,c) from the past
+	ldr	$t0,[$t3,#0]
+	ldr	$t1,[$t3,#4]
+	ldr	$t2,[$t3,#8]
+	add	$A,$A,$t0
+	ldr	$t0,[$t3,#12]
+	add	$B,$B,$t1
+	ldr	$t1,[$t3,#16]
+	add	$C,$C,$t2
+	ldr	$t2,[$t3,#20]
+	add	$D,$D,$t0
+	ldr	$t0,[$t3,#24]
+	add	$E,$E,$t1
+	ldr	$t1,[$t3,#28]
+	add	$F,$F,$t2
+	ldr	$inp,[sp,#17*4]		@ pull inp
+	ldr	$t2,[sp,#18*4]		@ pull inp+len
+	add	$G,$G,$t0
+	add	$H,$H,$t1
+	stmia	$t3,{$A,$B,$C,$D,$E,$F,$G,$H}
+	cmp	$inp,$t2
+	sub	$Ktbl,$Ktbl,#256	@ rewind Ktbl
+	bne	.Loop
+
+	add	sp,sp,#`16+3`*4	@ destroy frame
+#if __ARM_ARCH__>=5
+	ldmia	sp!,{r4-r11,pc}
+#else
+	ldmia	sp!,{r4-r11,lr}
+	tst	lr,#1
+	moveq	pc,lr			@ be binary compatible with V4, yet
+	bx	lr			@ interoperable with Thumb ISA:-)
+#endif
+.size	sha256_block_data_order,.-sha256_block_data_order
+___
+######################################################################
+# NEON stuff
+#
+{{{
+my @X=map("q$_",(0..3));
+my ($T0,$T1,$T2,$T3,$T4,$T5)=("q8","q9","q10","q11","d24","d25");
+my $Xfer=$t4;
+my $j=0;
+
+sub Dlo()   { shift=~m|q([1]?[0-9])|?"d".($1*2):"";     }
+sub Dhi()   { shift=~m|q([1]?[0-9])|?"d".($1*2+1):"";   }
+
+sub AUTOLOAD()          # thunk [simplified] x86-style perlasm
+{ my $opcode = $AUTOLOAD; $opcode =~ s/.*:://; $opcode =~ s/_/\./;
+  my $arg = pop;
+    $arg = "#$arg" if ($arg*1 eq $arg);
+    $code .= "\t$opcode\t".join(',', at _,$arg)."\n";
+}
+
+sub Xupdate()
+{ use integer;
+  my $body = shift;
+  my @insns = (&$body,&$body,&$body,&$body);
+  my ($a,$b,$c,$d,$e,$f,$g,$h);
+
+	&vext_8		($T0, at X[0], at X[1],4);	# X[1..4]
+	 eval(shift(@insns));
+	 eval(shift(@insns));
+	 eval(shift(@insns));
+	&vext_8		($T1, at X[2], at X[3],4);	# X[9..12]
+	 eval(shift(@insns));
+	 eval(shift(@insns));
+	 eval(shift(@insns));
+	&vshr_u32	($T2,$T0,$sigma0[0]);
+	 eval(shift(@insns));
+	 eval(shift(@insns));
+	&vadd_i32	(@X[0], at X[0],$T1);	# X[0..3] += X[9..12]
+	 eval(shift(@insns));
+	 eval(shift(@insns));
+	&vshr_u32	($T1,$T0,$sigma0[2]);
+	 eval(shift(@insns));
+	 eval(shift(@insns));
+	&vsli_32	($T2,$T0,32-$sigma0[0]);
+	 eval(shift(@insns));
+	 eval(shift(@insns));
+	&vshr_u32	($T3,$T0,$sigma0[1]);
+	 eval(shift(@insns));
+	 eval(shift(@insns));
+	&veor		($T1,$T1,$T2);
+	 eval(shift(@insns));
+	 eval(shift(@insns));
+	&vsli_32	($T3,$T0,32-$sigma0[1]);
+	 eval(shift(@insns));
+	 eval(shift(@insns));
+	  &vshr_u32	($T4,&Dhi(@X[3]),$sigma1[0]);
+	 eval(shift(@insns));
+	 eval(shift(@insns));
+	&veor		($T1,$T1,$T3);		# sigma0(X[1..4])
+	 eval(shift(@insns));
+	 eval(shift(@insns));
+	  &vsli_32	($T4,&Dhi(@X[3]),32-$sigma1[0]);
+	 eval(shift(@insns));
+	 eval(shift(@insns));
+	  &vshr_u32	($T5,&Dhi(@X[3]),$sigma1[2]);
+	 eval(shift(@insns));
+	 eval(shift(@insns));
+	&vadd_i32	(@X[0], at X[0],$T1);	# X[0..3] += sigma0(X[1..4])
+	 eval(shift(@insns));
+	 eval(shift(@insns));
+	  &veor		($T5,$T5,$T4);
+	 eval(shift(@insns));
+	 eval(shift(@insns));
+	  &vshr_u32	($T4,&Dhi(@X[3]),$sigma1[1]);
+	 eval(shift(@insns));
+	 eval(shift(@insns));
+	  &vsli_32	($T4,&Dhi(@X[3]),32-$sigma1[1]);
+	 eval(shift(@insns));
+	 eval(shift(@insns));
+	  &veor		($T5,$T5,$T4);		# sigma1(X[14..15])
+	 eval(shift(@insns));
+	 eval(shift(@insns));
+	&vadd_i32	(&Dlo(@X[0]),&Dlo(@X[0]),$T5);# X[0..1] += sigma1(X[14..15])
+	 eval(shift(@insns));
+	 eval(shift(@insns));
+	  &vshr_u32	($T4,&Dlo(@X[0]),$sigma1[0]);
+	 eval(shift(@insns));
+	 eval(shift(@insns));
+	  &vsli_32	($T4,&Dlo(@X[0]),32-$sigma1[0]);
+	 eval(shift(@insns));
+	 eval(shift(@insns));
+	  &vshr_u32	($T5,&Dlo(@X[0]),$sigma1[2]);
+	 eval(shift(@insns));
+	 eval(shift(@insns));
+	  &veor		($T5,$T5,$T4);
+	 eval(shift(@insns));
+	 eval(shift(@insns));
+	  &vshr_u32	($T4,&Dlo(@X[0]),$sigma1[1]);
+	 eval(shift(@insns));
+	 eval(shift(@insns));
+	&vld1_32	("{$T0}","[$Ktbl,:128]!");
+	 eval(shift(@insns));
+	 eval(shift(@insns));
+	  &vsli_32	($T4,&Dlo(@X[0]),32-$sigma1[1]);
+	 eval(shift(@insns));
+	 eval(shift(@insns));
+	  &veor		($T5,$T5,$T4);		# sigma1(X[16..17])
+	 eval(shift(@insns));
+	 eval(shift(@insns));
+	&vadd_i32	(&Dhi(@X[0]),&Dhi(@X[0]),$T5);# X[2..3] += sigma1(X[16..17])
+	 eval(shift(@insns));
+	 eval(shift(@insns));
+	&vadd_i32	($T0,$T0, at X[0]);
+	 while($#insns>=2) { eval(shift(@insns)); }
+	&vst1_32	("{$T0}","[$Xfer,:128]!");
+	 eval(shift(@insns));
+	 eval(shift(@insns));
+
+	push(@X,shift(@X));		# "rotate" X[]
+}
+
+sub Xpreload()
+{ use integer;
+  my $body = shift;
+  my @insns = (&$body,&$body,&$body,&$body);
+  my ($a,$b,$c,$d,$e,$f,$g,$h);
+
+	 eval(shift(@insns));
+	 eval(shift(@insns));
+	 eval(shift(@insns));
+	 eval(shift(@insns));
+	&vld1_32	("{$T0}","[$Ktbl,:128]!");
+	 eval(shift(@insns));
+	 eval(shift(@insns));
+	 eval(shift(@insns));
+	 eval(shift(@insns));
+	&vrev32_8	(@X[0], at X[0]);
+	 eval(shift(@insns));
+	 eval(shift(@insns));
+	 eval(shift(@insns));
+	 eval(shift(@insns));
+	&vadd_i32	($T0,$T0, at X[0]);
+	 foreach (@insns) { eval; }	# remaining instructions
+	&vst1_32	("{$T0}","[$Xfer,:128]!");
+
+	push(@X,shift(@X));		# "rotate" X[]
+}
+
+sub body_00_15 () {
+	(
+	'($a,$b,$c,$d,$e,$f,$g,$h)=@V;'.
+	'&add	($h,$h,$t1)',			# h+=X[i]+K[i]
+	'&eor	($t1,$f,$g)',
+	'&eor	($t0,$e,$e,"ror#".($Sigma1[1]-$Sigma1[0]))',
+	'&add	($a,$a,$t2)',			# h+=Maj(a,b,c) from the past
+	'&and	($t1,$t1,$e)',
+	'&eor	($t2,$t0,$e,"ror#".($Sigma1[2]-$Sigma1[0]))',	# Sigma1(e)
+	'&eor	($t0,$a,$a,"ror#".($Sigma0[1]-$Sigma0[0]))',
+	'&eor	($t1,$t1,$g)',			# Ch(e,f,g)
+	'&add	($h,$h,$t2,"ror#$Sigma1[0]")',	# h+=Sigma1(e)
+	'&eor	($t2,$a,$b)',			# a^b, b^c in next round
+	'&eor	($t0,$t0,$a,"ror#".($Sigma0[2]-$Sigma0[0]))',	# Sigma0(a)
+	'&add	($h,$h,$t1)',			# h+=Ch(e,f,g)
+	'&ldr	($t1,sprintf "[sp,#%d]",4*(($j+1)&15))	if (($j&15)!=15);'.
+	'&ldr	($t1,"[$Ktbl]")				if ($j==15);'.
+	'&ldr	($t1,"[sp,#64]")			if ($j==31)',

arch/arm/crypto/sha256-armv4.pl line 451

Quoted 10 lines
arch/arm/crypto/sha256-armv4.pl new file +10 -0
+	'&and	($t3,$t3,$t2)',			# (b^c)&=(a^b)
+	'&add	($d,$d,$h)',			# d+=h
+	'&add	($h,$h,$t0,"ror#$Sigma0[0]");'.	# h+=Sigma0(a)
+	'&eor	($t3,$t3,$b)',			# Maj(a,b,c)
+	'$j++;	unshift(@V,pop(@V)); ($t2,$t3)=($t3,$t2);'
+	)
+}
+
+$code.=<<___;
+#if __ARM_MAX_ARCH__>=7

this will be compile on armv4 but gcc will not allow it

we need to drop the neon code for older non v7 build

Best Regards,
J.

#16 lore raw

PATCH v2 1/1 arm: crypto: Add optimized SHA-256/224

Quoted 287 lines · Jean-Christophe PLAGNIOL-VILLARD
Quoted 286 lines · Sami Tolvanen

Add Andy Polyakov's optimized assembly and NEON implementations for SHA-256/224.

The sha256-armv4.pl script for generating the assembly code is from OpenSSL commit 2ecd32a1f8f0643ae7b38f59bbaf9f0d6ef326fe.

Compared to sha256-generic these implementations have the following tcrypt speed improvements on Motorola Nexus 6 (Snapdragon 805):

  bs    b/u      sha256-neon  sha256-asm
  16    16       x1.32        x1.19
  64    16       x1.27        x1.15
  64    64       x1.36        x1.20
  256   16       x1.22        x1.11
  256   64       x1.36        x1.19
  256   256      x1.59        x1.23
  1024  16       x1.21        x1.10
  1024  256      x1.65        x1.23
  1024  1024     x1.76        x1.25
  2048  16       x1.21        x1.10
  2048  256      x1.66        x1.23
  2048  1024     x1.78        x1.25
  2048  2048     x1.79        x1.25
  4096  16       x1.20        x1.09
  4096  256      x1.66        x1.23
  4096  1024     x1.79        x1.26
  4096  4096     x1.82        x1.26
  8192  16       x1.20        x1.09
  8192  256      x1.67        x1.23
  8192  1024     x1.80        x1.26
  8192  4096     x1.85        x1.28
  8192  8192     x1.85        x1.27

Where bs refers to block size and b/u to bytes per update.

---
Changes since v1:
Rebased to Herbert's cryptodev tree
Include sha256-armv4.pl and use it to generate sha256-core.S Add integer-only assembly version as sha256-asm Add support for SHA-224 to the glue code
Change priority for sha256/224-ce to 300

---
 arch/arm/crypto/Kconfig               |    7
 arch/arm/crypto/Makefile              |    8
 arch/arm/crypto/sha2-ce-glue.c        |    4
 arch/arm/crypto/sha256-armv4.pl       |  713 ++++++
 arch/arm/crypto/sha256-core.S_shipped | 2775 ++++++++++++++++++++++++
 arch/arm/crypto/sha256_glue.c         |  246 ++
 arch/arm/crypto/sha256_glue.h         |   23
 arch/arm/crypto/sha256_neon_glue.c    |  172 +
 8 files changed, 3945 insertions(+), 3 deletions(-)
arch/arm/crypto/Kconfig +7 -0
index d63f319..458729d 100644
@@ -46,6 +46,13 @@ config CRYPTO_SHA2_ARM_CE
        SHA-256 secure hash standard (DFIPS 180-2) implemented
        using special ARMv8 Crypto Extensions.
 
+config CRYPTO_SHA256_ARM
+     tristate "SHA-224/256 digest algorithm (ARM-asm and NEON)"
+     select CRYPTO_HASH
+     help
+       SHA-256 secure hash standard (DFIPS 180-2) implemented
+       using optimized ARM assembler and NEON, when available.
+
 config CRYPTO_SHA512_ARM_NEON
      tristate "SHA384 and SHA512 digest algorithm (ARM NEON)"
      depends on KERNEL_MODE_NEON
arch/arm/crypto/Makefile +7 -1
index 9a273bd..ef46e89 100644
@@ -7,6 +7,7 @@ obj-$(CONFIG_CRYPTO_AES_ARM_BS) += aes-arm-bs.o
 obj-$(CONFIG_CRYPTO_AES_ARM_CE) += aes-arm-ce.o
 obj-$(CONFIG_CRYPTO_SHA1_ARM) += sha1-arm.o
 obj-$(CONFIG_CRYPTO_SHA1_ARM_NEON) += sha1-arm-neon.o
+obj-$(CONFIG_CRYPTO_SHA256_ARM) += sha256-arm.o
 obj-$(CONFIG_CRYPTO_SHA512_ARM_NEON) += sha512-arm-neon.o
 obj-$(CONFIG_CRYPTO_SHA1_ARM_CE) += sha1-arm-ce.o
 obj-$(CONFIG_CRYPTO_SHA2_ARM_CE) += sha2-arm-ce.o
@@ -16,6 +17,8 @@ aes-arm-y   := aes-armv4.o aes_glue.o
 aes-arm-bs-y := aesbs-core.o aesbs-glue.o
 sha1-arm-y   := sha1-armv4-large.o sha1_glue.o
 sha1-arm-neon-y      := sha1-armv7-neon.o sha1_neon_glue.o
+sha256-arm-neon-$(CONFIG_KERNEL_MODE_NEON) := sha256_neon_glue.o
+sha256-arm-y := sha256-core.o sha256_glue.o $(sha256-arm-neon-y)
 sha512-arm-neon-y := sha512-armv7-neon.o sha512_neon_glue.o
 sha1-arm-ce-y        := sha1-ce-core.o sha1-ce-glue.o
 sha2-arm-ce-y        := sha2-ce-core.o sha2-ce-glue.o
@@ -28,4 +31,7 @@ quiet_cmd_perl = PERL    $@
 $(src)/aesbs-core.S_shipped: $(src)/bsaes-armv7.pl
      $(call cmd,perl)
 
-.PRECIOUS: $(obj)/aesbs-core.S
+$(src)/sha256-core.S_shipped: $(src)/sha256-armv4.pl
+     $(call cmd,perl)
+
+.PRECIOUS: $(obj)/aesbs-core.S $(obj)/sha256-core.S
arch/arm/crypto/sha2-ce-glue.c +2 -2
index 9ffe8ad..0449eca 100644
@@ -163,7 +163,7 @@ static struct shash_alg algs[] = { {
      .base                   = {
              .cra_name               = "sha224",
              .cra_driver_name        = "sha224-ce",
-             .cra_priority           = 200,
+             .cra_priority           = 300,
              .cra_flags              = CRYPTO_ALG_TYPE_SHASH,
              .cra_blocksize          = SHA256_BLOCK_SIZE,
              .cra_module             = THIS_MODULE,
@@ -180,7 +180,7 @@ static struct shash_alg algs[] = { {
      .base                   = {
              .cra_name               = "sha256",
              .cra_driver_name        = "sha256-ce",
-             .cra_priority           = 200,
+             .cra_priority           = 300,
              .cra_flags              = CRYPTO_ALG_TYPE_SHASH,
              .cra_blocksize          = SHA256_BLOCK_SIZE,
              .cra_module             = THIS_MODULE,
arch/arm/crypto/sha256-armv4.pl new file +153 -0
new file mode 100644
index 0000000..4fee74d
@@ -0,0 +1,713 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Written by Andy Polyakov <[email protected]> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+#
+# Permission to use under GPL terms is granted.
+# ====================================================================
+
+# SHA256 block procedure for ARMv4. May 2007.
+
+# Performance is ~2x better than gcc 3.4 generated code and in "abso-
+# lute" terms is ~2250 cycles per 64-byte block or ~35 cycles per
+# byte [on single-issue Xscale PXA250 core].
+
+# July 2010.
+#
+# Rescheduling for dual-issue pipeline resulted in 22% improvement on
+# Cortex A8 core and ~20 cycles per processed byte.
+
+# February 2011.
+#
+# Profiler-assisted and platform-specific optimization resulted in 16%
+# improvement on Cortex A8 core and ~15.4 cycles per processed byte.
+
+# September 2013.
+#
+# Add NEON implementation. On Cortex A8 it was measured to process one
+# byte in 12.5 cycles or 23% faster than integer-only code. Snapdragon
+# S4 does it in 12.5 cycles too, but it's 50% faster than integer-only
+# code (meaning that latter performs sub-optimally, nothing was done
+# about it).
+
+# May 2014.
+#
+# Add ARMv8 code path performing at 2.0 cpb on Apple A7.
+
+while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {}
+open STDOUT,">$output";
+
+$ctx="r0";   $t0="r0";
+$inp="r1";   $t4="r1";
+$len="r2";   $t1="r2";
+$T1="r3";    $t3="r3";
+$A="r4";
+$B="r5";
+$C="r6";
+$D="r7";
+$E="r8";
+$F="r9";
+$G="r10";
+$H="r11";
+ at V=($A,$B,$C,$D,$E,$F,$G,$H);
+$t2="r12";
+$Ktbl="r14";
+
+ at Sigma0=( 2,13,22);
+ at Sigma1=( 6,11,25);
+ at sigma0=( 7,18, 3);
+ at sigma1=(17,19,10);
+
+sub BODY_00_15 {
+my ($i,$a,$b,$c,$d,$e,$f,$g,$h) = @_;
+
+$code.=<<___ if ($i<16);
+#if __ARM_ARCH__>=7
+     @ ldr   $t1,[$inp],#4                   @ $i
+# if $i==15
+     str     $inp,[sp,#17*4]                 @ make room for $t4
+# endif
+     eor     $t0,$e,$e,ror#`$Sigma1[1]-$Sigma1[0]`
+     add     $a,$a,$t2                       @ h+=Maj(a,b,c) from the past
+     eor     $t0,$t0,$e,ror#`$Sigma1[2]-$Sigma1[0]`  @ Sigma1(e)
+     rev     $t1,$t1
+#else
+     @ ldrb  $t1,[$inp,#3]                   @ $i
+     add     $a,$a,$t2                       @ h+=Maj(a,b,c) from the past
+     ldrb    $t2,[$inp,#2]
+     ldrb    $t0,[$inp,#1]
+     orr     $t1,$t1,$t2,lsl#8
+     ldrb    $t2,[$inp],#4
+     orr     $t1,$t1,$t0,lsl#16
+# if $i==15
+     str     $inp,[sp,#17*4]                 @ make room for $t4
+# endif
+     eor     $t0,$e,$e,ror#`$Sigma1[1]-$Sigma1[0]`
+     orr     $t1,$t1,$t2,lsl#24
+     eor     $t0,$t0,$e,ror#`$Sigma1[2]-$Sigma1[0]`  @ Sigma1(e)
+#endif
+___
+$code.=<<___;
+     ldr     $t2,[$Ktbl],#4                  @ *K256++
+     add     $h,$h,$t1                       @ h+=X[i]
+     str     $t1,[sp,#`$i%16`*4]
+     eor     $t1,$f,$g
+     add     $h,$h,$t0,ror#$Sigma1[0]        @ h+=Sigma1(e)
+     and     $t1,$t1,$e
+     add     $h,$h,$t2                       @ h+=K256[i]
+     eor     $t1,$t1,$g                      @ Ch(e,f,g)
+     eor     $t0,$a,$a,ror#`$Sigma0[1]-$Sigma0[0]`
+     add     $h,$h,$t1                       @ h+=Ch(e,f,g)
+#if $i==31
+     and     $t2,$t2,#0xff
+     cmp     $t2,#0xf2                       @ done?
+#endif
+#if $i<15
+# if __ARM_ARCH__>=7
+     ldr     $t1,[$inp],#4                   @ prefetch
+# else
+     ldrb    $t1,[$inp,#3]
+# endif
+     eor     $t2,$a,$b                       @ a^b, b^c in next round
+#else
+     ldr     $t1,[sp,#`($i+2)%16`*4]         @ from future BODY_16_xx
+     eor     $t2,$a,$b                       @ a^b, b^c in next round
+     ldr     $t4,[sp,#`($i+15)%16`*4]        @ from future BODY_16_xx
+#endif
+     eor     $t0,$t0,$a,ror#`$Sigma0[2]-$Sigma0[0]`  @ Sigma0(a)
+     and     $t3,$t3,$t2                     @ (b^c)&=(a^b)
+     add     $d,$d,$h                        @ d+=h
+     eor     $t3,$t3,$b                      @ Maj(a,b,c)
+     add     $h,$h,$t0,ror#$Sigma0[0]        @ h+=Sigma0(a)
+     @ add   $h,$h,$t3                       @ h+=Maj(a,b,c)
+___
+     ($t2,$t3)=($t3,$t2);
+}
+
+sub BODY_16_XX {
+my ($i,$a,$b,$c,$d,$e,$f,$g,$h) = @_;
+
+$code.=<<___;
+     @ ldr   $t1,[sp,#`($i+1)%16`*4]         @ $i
+     @ ldr   $t4,[sp,#`($i+14)%16`*4]
+     mov     $t0,$t1,ror#$sigma0[0]
+     add     $a,$a,$t2                       @ h+=Maj(a,b,c) from the past
+     mov     $t2,$t4,ror#$sigma1[0]
+     eor     $t0,$t0,$t1,ror#$sigma0[1]
+     eor     $t2,$t2,$t4,ror#$sigma1[1]
+     eor     $t0,$t0,$t1,lsr#$sigma0[2]      @ sigma0(X[i+1])
+     ldr     $t1,[sp,#`($i+0)%16`*4]
+     eor     $t2,$t2,$t4,lsr#$sigma1[2]      @ sigma1(X[i+14])
+     ldr     $t4,[sp,#`($i+9)%16`*4]
+
+     add     $t2,$t2,$t0
+     eor     $t0,$e,$e,ror#`$Sigma1[1]-$Sigma1[0]`   @ from BODY_00_15
+     add     $t1,$t1,$t2
+     eor     $t0,$t0,$e,ror#`$Sigma1[2]-$Sigma1[0]`  @ Sigma1(e)
+     add     $t1,$t1,$t4                     @ X[i]
+___
+     &BODY_00_15(@_);
+}
Quoted 8 lines

arch/arm/crypto/sha256-armv4.pl line 160

Quoted 7 lines
arch/arm/crypto/sha256-armv4.pl new file +7 -0
+
+$code=<<___;
+#ifndef __KERNEL__
+# include "arm_arch.h"
+#else
+# define __ARM_ARCH__ __LINUX_ARM_ARCH__
+# define __ARM_MAX_ARCH__ 7

I'm not sure this will work for kernel that is for older arm

This code is only used at runtime if a NEON is detected on the current CPU

Quoted 293 lines
Quoted 281 lines
arch/arm/crypto/sha256-armv4.pl new file +281 -0
+#endif
+
+.text
+#if __ARM_ARCH__<7
+.code        32
+#else
+.syntax unified
+# ifdef __thumb2__
+.thumb
+# else
+.code   32
+# endif
+#endif
+
+.type        K256,%object
+.align       5
+K256:
+.word        0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5
+.word        0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5
+.word        0xd807aa98,0x12835b01,0x243185be,0x550c7dc3
+.word        0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174
+.word        0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc
+.word        0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da
+.word        0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7
+.word        0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967
+.word        0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13
+.word        0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85
+.word        0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3
+.word        0xd192e819,0xd6990624,0xf40e3585,0x106aa070
+.word        0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5
+.word        0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3
+.word        0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208
+.word        0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
+.size        K256,.-K256
+.word        0                               @ terminator
+#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__)
+.LOPENSSL_armcap:
+.word        OPENSSL_armcap_P-sha256_block_data_order
+#endif
+.align       5
+
+.global      sha256_block_data_order
+.type        sha256_block_data_order,%function
+sha256_block_data_order:
+#if __ARM_ARCH__<7
+     sub     r3,pc,#8                @ sha256_block_data_order
+#else
+     adr     r3,sha256_block_data_order
+#endif
+#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__)
+     ldr     r12,.LOPENSSL_armcap
+     ldr     r12,[r3,r12]            @ OPENSSL_armcap_P
+     tst     r12,#ARMV8_SHA256
+     bne     .LARMv8
+     tst     r12,#ARMV7_NEON
+     bne     .LNEON
+#endif
+     add     $len,$inp,$len,lsl#6    @ len to point at the end of inp
+     stmdb   sp!,{$ctx,$inp,$len,r4-r11,lr}
+     ldmia   $ctx,{$A,$B,$C,$D,$E,$F,$G,$H}
+     sub     $Ktbl,r3,#256+32        @ K256
+     sub     sp,sp,#16*4             @ alloca(X[16])
+.Loop:
+# if __ARM_ARCH__>=7
+     ldr     $t1,[$inp],#4
+# else
+     ldrb    $t1,[$inp,#3]
+# endif
+     eor     $t3,$B,$C               @ magic
+     eor     $t2,$t2,$t2
+___
+for($i=0;$i<16;$i++) { &BODY_00_15($i,@V); unshift(@V,pop(@V)); }
+$code.=".Lrounds_16_xx:\n";
+for (;$i<32;$i++)    { &BODY_16_XX($i,@V); unshift(@V,pop(@V)); }
+$code.=<<___;
+#if __ARM_ARCH__>=7
+     ite     eq                      @ Thumb2 thing, sanity check in ARM
+#endif
+     ldreq   $t3,[sp,#16*4]          @ pull ctx
+     bne     .Lrounds_16_xx
+
+     add     $A,$A,$t2               @ h+=Maj(a,b,c) from the past
+     ldr     $t0,[$t3,#0]
+     ldr     $t1,[$t3,#4]
+     ldr     $t2,[$t3,#8]
+     add     $A,$A,$t0
+     ldr     $t0,[$t3,#12]
+     add     $B,$B,$t1
+     ldr     $t1,[$t3,#16]
+     add     $C,$C,$t2
+     ldr     $t2,[$t3,#20]
+     add     $D,$D,$t0
+     ldr     $t0,[$t3,#24]
+     add     $E,$E,$t1
+     ldr     $t1,[$t3,#28]
+     add     $F,$F,$t2
+     ldr     $inp,[sp,#17*4]         @ pull inp
+     ldr     $t2,[sp,#18*4]          @ pull inp+len
+     add     $G,$G,$t0
+     add     $H,$H,$t1
+     stmia   $t3,{$A,$B,$C,$D,$E,$F,$G,$H}
+     cmp     $inp,$t2
+     sub     $Ktbl,$Ktbl,#256        @ rewind Ktbl
+     bne     .Loop
+
+     add     sp,sp,#`16+3`*4 @ destroy frame
+#if __ARM_ARCH__>=5
+     ldmia   sp!,{r4-r11,pc}
+#else
+     ldmia   sp!,{r4-r11,lr}
+     tst     lr,#1
+     moveq   pc,lr                   @ be binary compatible with V4, yet
+     bx      lr                      @ interoperable with Thumb ISA:-)
+#endif
+.size        sha256_block_data_order,.-sha256_block_data_order
+___
+######################################################################
+# NEON stuff
+#
+{{{
+my @X=map("q$_",(0..3));
+my ($T0,$T1,$T2,$T3,$T4,$T5)=("q8","q9","q10","q11","d24","d25");
+my $Xfer=$t4;
+my $j=0;
+
+sub Dlo()   { shift=~m|q([1]?[0-9])|?"d".($1*2):"";     }
+sub Dhi()   { shift=~m|q([1]?[0-9])|?"d".($1*2+1):"";   }
+
+sub AUTOLOAD()          # thunk [simplified] x86-style perlasm
+{ my $opcode = $AUTOLOAD; $opcode =~ s/.*:://; $opcode =~ s/_/\./;
+  my $arg = pop;
+    $arg = "#$arg" if ($arg*1 eq $arg);
+    $code .= "\t$opcode\t".join(',', at _,$arg)."\n";
+}
+
+sub Xupdate()
+{ use integer;
+  my $body = shift;
+  my @insns = (&$body,&$body,&$body,&$body);
+  my ($a,$b,$c,$d,$e,$f,$g,$h);
+
+     &vext_8         ($T0, at X[0], at X[1],4);    # X[1..4]
+      eval(shift(@insns));
+      eval(shift(@insns));
+      eval(shift(@insns));
+     &vext_8         ($T1, at X[2], at X[3],4);    # X[9..12]
+      eval(shift(@insns));
+      eval(shift(@insns));
+      eval(shift(@insns));
+     &vshr_u32       ($T2,$T0,$sigma0[0]);
+      eval(shift(@insns));
+      eval(shift(@insns));
+     &vadd_i32       (@X[0], at X[0],$T1);      # X[0..3] += X[9..12]
+      eval(shift(@insns));
+      eval(shift(@insns));
+     &vshr_u32       ($T1,$T0,$sigma0[2]);
+      eval(shift(@insns));
+      eval(shift(@insns));
+     &vsli_32        ($T2,$T0,32-$sigma0[0]);
+      eval(shift(@insns));
+      eval(shift(@insns));
+     &vshr_u32       ($T3,$T0,$sigma0[1]);
+      eval(shift(@insns));
+      eval(shift(@insns));
+     &veor           ($T1,$T1,$T2);
+      eval(shift(@insns));
+      eval(shift(@insns));
+     &vsli_32        ($T3,$T0,32-$sigma0[1]);
+      eval(shift(@insns));
+      eval(shift(@insns));
+       &vshr_u32     ($T4,&Dhi(@X[3]),$sigma1[0]);
+      eval(shift(@insns));
+      eval(shift(@insns));
+     &veor           ($T1,$T1,$T3);          # sigma0(X[1..4])
+      eval(shift(@insns));
+      eval(shift(@insns));
+       &vsli_32      ($T4,&Dhi(@X[3]),32-$sigma1[0]);
+      eval(shift(@insns));
+      eval(shift(@insns));
+       &vshr_u32     ($T5,&Dhi(@X[3]),$sigma1[2]);
+      eval(shift(@insns));
+      eval(shift(@insns));
+     &vadd_i32       (@X[0], at X[0],$T1);      # X[0..3] += sigma0(X[1..4])
+      eval(shift(@insns));
+      eval(shift(@insns));
+       &veor         ($T5,$T5,$T4);
+      eval(shift(@insns));
+      eval(shift(@insns));
+       &vshr_u32     ($T4,&Dhi(@X[3]),$sigma1[1]);
+      eval(shift(@insns));
+      eval(shift(@insns));
+       &vsli_32      ($T4,&Dhi(@X[3]),32-$sigma1[1]);
+      eval(shift(@insns));
+      eval(shift(@insns));
+       &veor         ($T5,$T5,$T4);          # sigma1(X[14..15])
+      eval(shift(@insns));
+      eval(shift(@insns));
+     &vadd_i32       (&Dlo(@X[0]),&Dlo(@X[0]),$T5);# X[0..1] += sigma1(X[14..15])
+      eval(shift(@insns));
+      eval(shift(@insns));
+       &vshr_u32     ($T4,&Dlo(@X[0]),$sigma1[0]);
+      eval(shift(@insns));
+      eval(shift(@insns));
+       &vsli_32      ($T4,&Dlo(@X[0]),32-$sigma1[0]);
+      eval(shift(@insns));
+      eval(shift(@insns));
+       &vshr_u32     ($T5,&Dlo(@X[0]),$sigma1[2]);
+      eval(shift(@insns));
+      eval(shift(@insns));
+       &veor         ($T5,$T5,$T4);
+      eval(shift(@insns));
+      eval(shift(@insns));
+       &vshr_u32     ($T4,&Dlo(@X[0]),$sigma1[1]);
+      eval(shift(@insns));
+      eval(shift(@insns));
+     &vld1_32        ("{$T0}","[$Ktbl,:128]!");
+      eval(shift(@insns));
+      eval(shift(@insns));
+       &vsli_32      ($T4,&Dlo(@X[0]),32-$sigma1[1]);
+      eval(shift(@insns));
+      eval(shift(@insns));
+       &veor         ($T5,$T5,$T4);          # sigma1(X[16..17])
+      eval(shift(@insns));
+      eval(shift(@insns));
+     &vadd_i32       (&Dhi(@X[0]),&Dhi(@X[0]),$T5);# X[2..3] += sigma1(X[16..17])
+      eval(shift(@insns));
+      eval(shift(@insns));
+     &vadd_i32       ($T0,$T0, at X[0]);
+      while($#insns>=2) { eval(shift(@insns)); }
+     &vst1_32        ("{$T0}","[$Xfer,:128]!");
+      eval(shift(@insns));
+      eval(shift(@insns));
+
+     push(@X,shift(@X));             # "rotate" X[]
+}
+
+sub Xpreload()
+{ use integer;
+  my $body = shift;
+  my @insns = (&$body,&$body,&$body,&$body);
+  my ($a,$b,$c,$d,$e,$f,$g,$h);
+
+      eval(shift(@insns));
+      eval(shift(@insns));
+      eval(shift(@insns));
+      eval(shift(@insns));
+     &vld1_32        ("{$T0}","[$Ktbl,:128]!");
+      eval(shift(@insns));
+      eval(shift(@insns));
+      eval(shift(@insns));
+      eval(shift(@insns));
+     &vrev32_8       (@X[0], at X[0]);
+      eval(shift(@insns));
+      eval(shift(@insns));
+      eval(shift(@insns));
+      eval(shift(@insns));
+     &vadd_i32       ($T0,$T0, at X[0]);
+      foreach (@insns) { eval; }     # remaining instructions
+     &vst1_32        ("{$T0}","[$Xfer,:128]!");
+
+     push(@X,shift(@X));             # "rotate" X[]
+}
+
+sub body_00_15 () {
+     (
+     '($a,$b,$c,$d,$e,$f,$g,$h)=@V;'.
+     '&add   ($h,$h,$t1)',                   # h+=X[i]+K[i]
+     '&eor   ($t1,$f,$g)',
+     '&eor   ($t0,$e,$e,"ror#".($Sigma1[1]-$Sigma1[0]))',
+     '&add   ($a,$a,$t2)',                   # h+=Maj(a,b,c) from the past
+     '&and   ($t1,$t1,$e)',
+     '&eor   ($t2,$t0,$e,"ror#".($Sigma1[2]-$Sigma1[0]))',   # Sigma1(e)
+     '&eor   ($t0,$a,$a,"ror#".($Sigma0[1]-$Sigma0[0]))',
+     '&eor   ($t1,$t1,$g)',                  # Ch(e,f,g)
+     '&add   ($h,$h,$t2,"ror#$Sigma1[0]")',  # h+=Sigma1(e)
+     '&eor   ($t2,$a,$b)',                   # a^b, b^c in next round
+     '&eor   ($t0,$t0,$a,"ror#".($Sigma0[2]-$Sigma0[0]))',   # Sigma0(a)
+     '&add   ($h,$h,$t1)',                   # h+=Ch(e,f,g)
+     '&ldr   ($t1,sprintf "[sp,#%d]",4*(($j+1)&15))  if (($j&15)!=15);'.
+     '&ldr   ($t1,"[$Ktbl]")                         if ($j==15);'.
+     '&ldr   ($t1,"[sp,#64]")                        if ($j==31)',

arch/arm/crypto/sha256-armv4.pl line 451

Quoted 10 lines
arch/arm/crypto/sha256-armv4.pl new file +10 -0
+     '&and   ($t3,$t3,$t2)',                 # (b^c)&=(a^b)
+     '&add   ($d,$d,$h)',                    # d+=h
+     '&add   ($h,$h,$t0,"ror#$Sigma0[0]");'. # h+=Sigma0(a)
+     '&eor   ($t3,$t3,$b)',                  # Maj(a,b,c)
+     '$j++;  unshift(@V,pop(@V)); ($t2,$t3)=($t3,$t2);'
+     )
+}
+
+$code.=<<___;
+#if __ARM_MAX_ARCH__>=7

this will be compile on armv4 but gcc will not allow it

Quoted 2 lines

we need to drop the neon code for older non v7 build

The .arch and .fpu declarations ensure that it can be built regardless of the platform you are compiling for, unless you have a really old toolchain.
The glue code ensures that the module can only be loaded if HWCAP_NEON is set.

Did you get errors trying to build it?

#17 lore raw

PATCH v2 1/1 arm: crypto: Add optimized SHA-256/224

Quoted 17 lines
Quoted 17 lines

+ '&eor ($t0,$t0,$a,"ror#".($Sigma0[2]-$Sigma0[0]))', # Sigma0(a)

Quoted 4 lines
arch/arm/crypto/sha256-armv4.pl new file +4 -0
+     '&add   ($h,$h,$t1)',                   # h+=Ch(e,f,g)
+     '&ldr   ($t1,sprintf "[sp,#%d]",4*(($j+1)&15))  if (($j&15)!=15);'.
+     '&ldr   ($t1,"[$Ktbl]")                         if ($j==15);'.
+     '&ldr   ($t1,"[sp,#64]")                        if ($j==31)',

arch/arm/crypto/sha256-armv4.pl line 451

Quoted 10 lines
arch/arm/crypto/sha256-armv4.pl new file +10 -0
+     '&and   ($t3,$t3,$t2)',                 # (b^c)&=(a^b)
+     '&add   ($d,$d,$h)',                    # d+=h
+     '&add   ($h,$h,$t0,"ror#$Sigma0[0]");'. # h+=Sigma0(a)
+     '&eor   ($t3,$t3,$b)',                  # Maj(a,b,c)
+     '$j++;  unshift(@V,pop(@V)); ($t2,$t3)=($t3,$t2);'
+     )
+}
+
+$code.=<<___;
+#if __ARM_MAX_ARCH__>=7

this will be compile on armv4 but gcc will not allow it

Quoted 6 lines
Quoted 2 lines

we need to drop the neon code for older non v7 build

The .arch and .fpu declarations ensure that it can be built regardless of the platform you are compiling for, unless you have a really old toolchain.

I known but does not work for me

Quoted 3 lines

The glue code ensures that the module can only be loaded if HWCAP_NEON is set.

Did you get errors trying to build it?

yes I do

I use

arm-none-linux-gnueabi-gcc (Sourcery CodeBench Lite 2014.05-29) 4.8.3 20140320 (prerelease)
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

so it's not that old

Best Regards,
J.

#18 lore raw

PATCH v2 1/1 arm: crypto: Add optimized SHA-256/224

Quoted 32 lines · Jean-Christophe PLAGNIOL-VILLARD
Quoted 17 lines
Quoted 17 lines

+ '&eor ($t0,$t0,$a,"ror#".($Sigma0[2]-$Sigma0[0]))', # Sigma0(a)

Quoted 4 lines
arch/arm/crypto/sha256-armv4.pl new file +4 -0
+     '&add   ($h,$h,$t1)',                   # h+=Ch(e,f,g)
+     '&ldr   ($t1,sprintf "[sp,#%d]",4*(($j+1)&15))  if (($j&15)!=15);'.
+     '&ldr   ($t1,"[$Ktbl]")                         if ($j==15);'.
+     '&ldr   ($t1,"[sp,#64]")                        if ($j==31)',

arch/arm/crypto/sha256-armv4.pl line 451

Quoted 10 lines
arch/arm/crypto/sha256-armv4.pl new file +10 -0
+     '&and   ($t3,$t3,$t2)',                 # (b^c)&=(a^b)
+     '&add   ($d,$d,$h)',                    # d+=h
+     '&add   ($h,$h,$t0,"ror#$Sigma0[0]");'. # h+=Sigma0(a)
+     '&eor   ($t3,$t3,$b)',                  # Maj(a,b,c)
+     '$j++;  unshift(@V,pop(@V)); ($t2,$t3)=($t3,$t2);'
+     )
+}
+
+$code.=<<___;
+#if __ARM_MAX_ARCH__>=7

this will be compile on armv4 but gcc will not allow it

Quoted 6 lines
Quoted 2 lines

we need to drop the neon code for older non v7 build

The .arch and .fpu declarations ensure that it can be built regardless of the platform you are compiling for, unless you have a really old toolchain.

I known but does not work for me

Quoted 3 lines

The glue code ensures that the module can only be loaded if HWCAP_NEON is set.

Did you get errors trying to build it?

yes I do

I use

Quoted 8 lines

arm-none-linux-gnueabi-gcc (Sourcery CodeBench Lite 2014.05-29) 4.8.3 20140320 (prerelease)
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

so it's not that old

Could you share the error log please?

#19 lore raw

PATCH v2 1/1 arm: crypto: Add optimized SHA-256/224

Quoted 40 lines · Ard Biesheuvel
Quoted 38 lines · Jean-Christophe PLAGNIOL-VILLARD
Quoted 17 lines
Quoted 17 lines

+ '&eor ($t0,$t0,$a,"ror#".($Sigma0[2]-$Sigma0[0]))', # Sigma0(a)

Quoted 4 lines
arch/arm/crypto/sha256-armv4.pl new file +4 -0
+     '&add   ($h,$h,$t1)',                   # h+=Ch(e,f,g)
+     '&ldr   ($t1,sprintf "[sp,#%d]",4*(($j+1)&15))  if (($j&15)!=15);'.
+     '&ldr   ($t1,"[$Ktbl]")                         if ($j==15);'.
+     '&ldr   ($t1,"[sp,#64]")                        if ($j==31)',

arch/arm/crypto/sha256-armv4.pl line 451

Quoted 10 lines
arch/arm/crypto/sha256-armv4.pl new file +10 -0
+     '&and   ($t3,$t3,$t2)',                 # (b^c)&=(a^b)
+     '&add   ($d,$d,$h)',                    # d+=h
+     '&add   ($h,$h,$t0,"ror#$Sigma0[0]");'. # h+=Sigma0(a)
+     '&eor   ($t3,$t3,$b)',                  # Maj(a,b,c)
+     '$j++;  unshift(@V,pop(@V)); ($t2,$t3)=($t3,$t2);'
+     )
+}
+
+$code.=<<___;
+#if __ARM_MAX_ARCH__>=7

this will be compile on armv4 but gcc will not allow it

Quoted 6 lines
Quoted 2 lines

we need to drop the neon code for older non v7 build

The .arch and .fpu declarations ensure that it can be built regardless of the platform you are compiling for, unless you have a really old toolchain.

I known but does not work for me

Quoted 3 lines

The glue code ensures that the module can only be loaded if HWCAP_NEON is set.

Did you get errors trying to build it?

yes I do

I use

arm-none-linux-gnueabi-gcc (Sourcery CodeBench Lite 2014.05-29) 4.8.3 20140320 (prerelease)
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Quoted 4 lines
Quoted 2 lines

so it's not that old

Could you share the error log please?

OK, I spotted one issue with this code:

arch/arm/crypto/sha256-core.S: Assembler messages:
arch/arm/crypto/sha256-core.S:1847: Error: invalid constant (ffffefb0) after fixup

This is caused by the fact that, when building the integer-only code for an older architecture, the conditional compilation produces a slightly bigger preceding function, and the symbol K256 is out of range for the adr instruction.

@Jean-Christophe: is that the same problem that you hit?

@Andy: I propose we do something similar as in the bsaes code:

#ifdef __thumb__
#define adrl adr
#endif

and replace the offending line with

adrl r14,K256

@Herbert: we will need to respin this, so please don't pull it yet.

Regards,

Signature · 1 line
Ard.
#20 lore raw

PATCH v2 1/1 arm: crypto: Add optimized SHA-256/224

Quoted 44 lines · Ard Biesheuvel
Quoted 43 lines · Ard Biesheuvel
Quoted 40 lines · Jean-Christophe PLAGNIOL-VILLARD
Quoted 17 lines
Quoted 17 lines

+ '&eor ($t0,$t0,$a,"ror#".($Sigma0[2]-$Sigma0[0]))', # Sigma0(a)

Quoted 4 lines
arch/arm/crypto/sha256-armv4.pl new file +4 -0
+     '&add   ($h,$h,$t1)',                   # h+=Ch(e,f,g)
+     '&ldr   ($t1,sprintf "[sp,#%d]",4*(($j+1)&15))  if (($j&15)!=15);'.
+     '&ldr   ($t1,"[$Ktbl]")                         if ($j==15);'.
+     '&ldr   ($t1,"[sp,#64]")                        if ($j==31)',

arch/arm/crypto/sha256-armv4.pl line 451

Quoted 10 lines
arch/arm/crypto/sha256-armv4.pl new file +10 -0
+     '&and   ($t3,$t3,$t2)',                 # (b^c)&=(a^b)
+     '&add   ($d,$d,$h)',                    # d+=h
+     '&add   ($h,$h,$t0,"ror#$Sigma0[0]");'. # h+=Sigma0(a)
+     '&eor   ($t3,$t3,$b)',                  # Maj(a,b,c)
+     '$j++;  unshift(@V,pop(@V)); ($t2,$t3)=($t3,$t2);'
+     )
+}
+
+$code.=<<___;
+#if __ARM_MAX_ARCH__>=7

this will be compile on armv4 but gcc will not allow it

Quoted 6 lines
Quoted 2 lines

we need to drop the neon code for older non v7 build

The .arch and .fpu declarations ensure that it can be built regardless of the platform you are compiling for, unless you have a really old toolchain.

I known but does not work for me

Quoted 3 lines

The glue code ensures that the module can only be loaded if HWCAP_NEON is set.

Did you get errors trying to build it?

yes I do

I use

arm-none-linux-gnueabi-gcc (Sourcery CodeBench Lite 2014.05-29) 4.8.3 20140320 (prerelease)
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

so it's not that old

Quoted 7 lines
Quoted 1 line

Could you share the error log please?

OK, I spotted one issue with this code:

arch/arm/crypto/sha256-core.S: Assembler messages:
arch/arm/crypto/sha256-core.S:1847: Error: invalid constant (ffffefb0) after fixup

yes exactly

Quoted 5 lines

This is caused by the fact that, when building the integer-only code for an older architecture, the conditional compilation produces a slightly bigger preceding function, and the symbol K256 is out of range for the adr instruction.

Yeap I see that too when debuging

Quoted 5 lines

@Jean-Christophe: is that the same problem that you hit?

@Andy: I propose we do something similar as in the bsaes code:

Quoted 7 lines

#ifdef __thumb__
#define adrl adr
#endif

and replace the offending line with

adrl r14,K256

on arm926ejs

Best Regards,
J.

#21 lore raw

PATCH v2 1/1 arm: crypto: Add optimized SHA-256/224

Quoted 70 lines · Jean-Christophe PLAGNIOL-VILLARD
Quoted 44 lines · Ard Biesheuvel
Quoted 43 lines · Ard Biesheuvel
Quoted 40 lines · Jean-Christophe PLAGNIOL-VILLARD
Quoted 17 lines
Quoted 17 lines

+ '&eor ($t0,$t0,$a,"ror#".($Sigma0[2]-$Sigma0[0]))', # Sigma0(a)

Quoted 4 lines
(quoted diff) +4 -0
+     '&add   ($h,$h,$t1)',                   # h+=Ch(e,f,g)
+     '&ldr   ($t1,sprintf "[sp,#%d]",4*(($j+1)&15))  if (($j&15)!=15);'.
+     '&ldr   ($t1,"[$Ktbl]")                         if ($j==15);'.
+     '&ldr   ($t1,"[sp,#64]")                        if ($j==31)',

Review

Quoted 10 lines
(quoted diff) +10 -0
+     '&and   ($t3,$t3,$t2)',                 # (b^c)&=(a^b)
+     '&add   ($d,$d,$h)',                    # d+=h
+     '&add   ($h,$h,$t0,"ror#$Sigma0[0]");'. # h+=Sigma0(a)
+     '&eor   ($t3,$t3,$b)',                  # Maj(a,b,c)
+     '$j++;  unshift(@V,pop(@V)); ($t2,$t3)=($t3,$t2);'
+     )
+}
+
+$code.=<<___;
+#if __ARM_MAX_ARCH__>=7

this will be compile on armv4 but gcc will not allow it

Quoted 6 lines
Quoted 2 lines

we need to drop the neon code for older non v7 build

The .arch and .fpu declarations ensure that it can be built regardless of the platform you are compiling for, unless you have a really old toolchain.

I known but does not work for me

Quoted 3 lines

The glue code ensures that the module can only be loaded if HWCAP_NEON is set.

Did you get errors trying to build it?

yes I do

I use

arm-none-linux-gnueabi-gcc (Sourcery CodeBench Lite 2014.05-29) 4.8.3 20140320 (prerelease)
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

so it's not that old

Quoted 7 lines
Quoted 1 line

Could you share the error log please?

OK, I spotted one issue with this code:

arch/arm/crypto/sha256-core.S: Assembler messages:
arch/arm/crypto/sha256-core.S:1847: Error: invalid constant (ffffefb0) after fixup

yes exactly

Quoted 5 lines

This is caused by the fact that, when building the integer-only code for an older architecture, the conditional compilation produces a slightly bigger preceding function, and the symbol K256 is out of range for the adr instruction.

Yeap I see that too when debuging

Quoted 9 lines

@Jean-Christophe: is that the same problem that you hit?

@Andy: I propose we do something similar as in the bsaes code:

#ifdef __thumb__
#define adrl adr
#endif

Quoted 7 lines
Quoted 3 lines

and replace the offending line with

adrl r14,K256

Thanks!

@Sami, Andy: we need to respin the whole patch, including updated OpenSSL upstream commit id :-(

Regards,
Ard.

#22 lore raw

PATCH v2 1/1 arm: crypto: Add optimized SHA-256/224

Quoted 2 lines · Ard Biesheuvel

@Sami, Andy: we need to respin the whole patch, including updated OpenSSL upstream commit id :-(

Sure, I will send v3 once the changes are in OpenSSL. Thanks for testing! Do you still prefer everything in one patch?

Sami

#23 lore raw

PATCH v2 1/1 arm: crypto: Add optimized SHA-256/224

Quoted 7 lines · Sami Tolvanen
Quoted 2 lines · Ard Biesheuvel

@Sami, Andy: we need to respin the whole patch, including updated OpenSSL upstream commit id :-(

Sure, I will send v3 once the changes are in OpenSSL. Thanks for testing! Do you still prefer everything in one patch?

If it is easily done, you could add the .S_swapped file and the related Makefile rule in a separate followup patch, yes. But then, the second one might still be too big ...

#24 lore raw

PATCH v2 1/1 arm: crypto: Add optimized SHA-256/224

In reply to Ard Biesheuvel
Quoted 17 lines
Quoted 1 line

Could you share the error log please?

OK, I spotted one issue with this code:

arch/arm/crypto/sha256-core.S: Assembler messages:
arch/arm/crypto/sha256-core.S:1847: Error: invalid constant (ffffefb0) after fixup

This is caused by the fact that, when building the integer-only code for an older architecture, the conditional compilation produces a slightly bigger preceding function, and the symbol K256 is out of range for the adr instruction.

@Jean-Christophe: is that the same problem that you hit?

@Andy: I propose we do something similar as in the bsaes code:

Quoted 7 lines

#ifdef __thumb__
#define adrl adr
#endif

and replace the offending line with

adrl r14,K256

Sorry about delay. Yes, that would do. I did test all combinations, but all "my" combinations, i.e. without __KERNEL__ defined :-( And without __KERNEL__ there are few extra instructions in integer-only subroutine that "push" instruction in question code toward higher address, so that constant was ffffefc0, which can be encoded. Anyway, I've chosen to add that #define next to .thumb directive. See attached.

Ard, you have mentioned that you've verified it on big-endian, but I've spotted little-endian dependency (see #ifndef __ARMEB__ in attached). I guess that it worked for you either because it was NEON that was tested (it does work as is) or __LINUX_ARM_ARCH__ was less than 7 (in which case it uses endian-neutral byte-by-byte data load). Can you confirm either?

-------------- next part --------------
A non-text attachment was scrubbed...
Name: sha256-armv4.diff
Type: text/x-patch
Size: 838 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150327/6d108844/attachment.bin>

#25 lore raw

PATCH v2 1/1 arm: crypto: Add optimized SHA-256/224

Quoted 32 lines · Andy Polyakov
Quoted 17 lines
Quoted 1 line

Could you share the error log please?

OK, I spotted one issue with this code:

arch/arm/crypto/sha256-core.S: Assembler messages:
arch/arm/crypto/sha256-core.S:1847: Error: invalid constant (ffffefb0) after fixup

This is caused by the fact that, when building the integer-only code for an older architecture, the conditional compilation produces a slightly bigger preceding function, and the symbol K256 is out of range for the adr instruction.

@Jean-Christophe: is that the same problem that you hit?

@Andy: I propose we do something similar as in the bsaes code:

Quoted 7 lines

#ifdef __thumb__
#define adrl adr
#endif

and replace the offending line with

adrl r14,K256

Sorry about delay. Yes, that would do. I did test all combinations, but all "my" combinations, i.e. without __KERNEL__ defined :-( And without __KERNEL__ there are few extra instructions in integer-only subroutine that "push" instruction in question code toward higher address, so that constant was ffffefc0, which can be encoded. Anyway, I've chosen to add that #define next to .thumb directive. See attached.

Quoted 6 lines

Ard, you have mentioned that you've verified it on big-endian, but I've spotted little-endian dependency (see #ifndef __ARMEB__ in attached). I guess that it worked for you either because it was NEON that was tested (it does work as is) or __LINUX_ARM_ARCH__ was less than 7 (in which case it uses endian-neutral byte-by-byte data load). Can you confirm either?

I need to double check that, but my suspicion is that it was the latter.

#26 lore raw

PATCH v2 1/1 arm: crypto: Add optimized SHA-256/224

Quoted 33 lines · Ard Biesheuvel
Quoted 32 lines · Andy Polyakov
Quoted 17 lines
Quoted 1 line

Could you share the error log please?

OK, I spotted one issue with this code:

arch/arm/crypto/sha256-core.S: Assembler messages:
arch/arm/crypto/sha256-core.S:1847: Error: invalid constant (ffffefb0) after fixup

This is caused by the fact that, when building the integer-only code for an older architecture, the conditional compilation produces a slightly bigger preceding function, and the symbol K256 is out of range for the adr instruction.

@Jean-Christophe: is that the same problem that you hit?

@Andy: I propose we do something similar as in the bsaes code:

Quoted 7 lines

#ifdef __thumb__
#define adrl adr
#endif

and replace the offending line with

adrl r14,K256

Sorry about delay. Yes, that would do. I did test all combinations, but all "my" combinations, i.e. without __KERNEL__ defined :-( And without __KERNEL__ there are few extra instructions in integer-only subroutine that "push" instruction in question code toward higher address, so that constant was ffffefc0, which can be encoded. Anyway, I've chosen to add that #define next to .thumb directive. See attached.

Quoted 8 lines
Quoted 6 lines

Ard, you have mentioned that you've verified it on big-endian, but I've spotted little-endian dependency (see #ifndef __ARMEB__ in attached). I guess that it worked for you either because it was NEON that was tested (it does work as is) or __LINUX_ARM_ARCH__ was less than 7 (in which case it uses endian-neutral byte-by-byte data load). Can you confirm either?

I need to double check that, but my suspicion is that it was the latter.

Indeed, if I build for v7 I get

[    0.269418] 00000000: 4e a5 c5 08 a6 56 6e 76 24 05 43 f8 fe b0 6f d4
[    0.275261] 00000010: 57 77 7b e3 95 49 c4 01 64 36 af da 65 d2 33 0e
[    0.281031] alg: hash: Test 1 failed for sha224-asm
[    0.285315] 00000000: 9d 6a 5d e9 e1 6c 39 99 c7 14 84 0f 47 77 1f 36
[    0.290912] 00000010: dc c2 97 a7 bd ef aa c3 6c 95 15 ae

which is indeed the integer code failing, and your attached patch fixes it.

#27 lore raw

PATCH v2 1/1 arm: crypto: Add optimized SHA-256/224

Quoted 21 lines
Quoted 11 lines
Quoted 11 lines
Quoted 11 lines

arch/arm/crypto/sha256-core.S: Assembler messages:
arch/arm/crypto/sha256-core.S:1847: Error: invalid constant (ffffefb0) after fixup

This is caused by the fact that, when building the integer-only code for an older architecture, the conditional compilation produces a slightly bigger preceding function, and the symbol K256 is out of range for the adr instruction.

... and replace the offending line with

Quoted 7 lines
Quoted 7 lines
Quoted 1 line

adrl r14,K256

Ard, you have mentioned that you've verified it on big-endian, but I've spotted little-endian dependency (see #ifndef __ARMEB__ in attached). I guess that it worked for you either because it was NEON that was tested (it does work as is) or __LINUX_ARM_ARCH__ was less than 7 (in which case it uses endian-neutral byte-by-byte data load). Can you confirm either?

Indeed, if I build for v7 I get

Quoted 7 lines
[    0.269418] 00000000: 4e a5 c5 08 a6 56 6e 76 24 05 43 f8 fe b0 6f d4
[    0.275261] 00000010: 57 77 7b e3 95 49 c4 01 64 36 af da 65 d2 33 0e
[    0.281031] alg: hash: Test 1 failed for sha224-asm
[    0.285315] 00000000: 9d 6a 5d e9 e1 6c 39 99 c7 14 84 0f 47 77 1f 36
[    0.290912] 00000010: dc c2 97 a7 bd ef aa c3 6c 95 15 ae

which is indeed the integer code failing, and your attached patch fixes it.

Committed as
http://git.openssl.org/gitweb/?p=openssl.git;a=commitdiff;h=51f8d095562f36cdaa6893597b5c609e943b0565.

#28 lore raw

PATCH v3 1/1 arm: crypto: Add optimized SHA-256/224

In reply to Sami Tolvanen

Add Andy Polyakov's optimized assembly and NEON implementations for SHA-256/224.

The sha256-armv4.pl script for generating the assembly code is from OpenSSL commit 51f8d095562f36cdaa6893597b5c609e943b0565.

Compared to sha256-generic these implementations have the following tcrypt speed improvements on Motorola Nexus 6 (Snapdragon 805):

  bs    b/u      sha256-neon  sha256-asm
  16    16       x1.32        x1.19
  64    16       x1.27        x1.15
  64    64       x1.36        x1.20
  256   16       x1.22        x1.11
  256   64       x1.36        x1.19
  256   256      x1.59        x1.23
  1024  16       x1.21        x1.10
  1024  256      x1.65        x1.23
  1024  1024     x1.76        x1.25
  2048  16       x1.21        x1.10
  2048  256      x1.66        x1.23
  2048  1024     x1.78        x1.25
  2048  2048     x1.79        x1.25
  4096  16       x1.20        x1.09
  4096  256      x1.66        x1.23
  4096  1024     x1.79        x1.26
  4096  4096     x1.82        x1.26
  8192  16       x1.20        x1.09
  8192  256      x1.67        x1.23
  8192  1024     x1.80        x1.26
  8192  4096     x1.85        x1.28
  8192  8192     x1.85        x1.27

Where bs refers to block size and b/u to bytes per update.

---
Changes since v2:
Updated sha256-armv4.pl and sha256-core.S_shipped

Changes since v1:
Rebased to Herbert's cryptodev tree
Include sha256-armv4.pl and use it to generate sha256-core.S Add integer-only assembly version as sha256-asm Add support for SHA-224 to the glue code
Change priority for sha256/224-ce to 300

---
 arch/arm/crypto/Kconfig               |    7 
 arch/arm/crypto/Makefile              |    8 
 arch/arm/crypto/sha2-ce-glue.c        |    4 
 arch/arm/crypto/sha256-armv4.pl       |  713 ++++++
 arch/arm/crypto/sha256-core.S_shipped | 2775 ++++++++++++++++++++++++
 arch/arm/crypto/sha256_glue.c         |  246 ++
 arch/arm/crypto/sha256_glue.h         |   23 
 arch/arm/crypto/sha256_neon_glue.c    |  172 +
 8 files changed, 3945 insertions(+), 3 deletions(-)
arch/arm/crypto/Kconfig +7 -0
index d63f319..458729d 100644
@@ -46,6 +46,13 @@ config CRYPTO_SHA2_ARM_CE
 	  SHA-256 secure hash standard (DFIPS 180-2) implemented
 	  using special ARMv8 Crypto Extensions.
 
+config CRYPTO_SHA256_ARM
+	tristate "SHA-224/256 digest algorithm (ARM-asm and NEON)"
+	select CRYPTO_HASH
+	help
+	  SHA-256 secure hash standard (DFIPS 180-2) implemented
+	  using optimized ARM assembler and NEON, when available.
+
 config CRYPTO_SHA512_ARM_NEON
 	tristate "SHA384 and SHA512 digest algorithm (ARM NEON)"
 	depends on KERNEL_MODE_NEON
arch/arm/crypto/Makefile +7 -1
index 9a273bd..ef46e89 100644
@@ -7,6 +7,7 @@ obj-$(CONFIG_CRYPTO_AES_ARM_BS) += aes-arm-bs.o
 obj-$(CONFIG_CRYPTO_AES_ARM_CE) += aes-arm-ce.o
 obj-$(CONFIG_CRYPTO_SHA1_ARM) += sha1-arm.o
 obj-$(CONFIG_CRYPTO_SHA1_ARM_NEON) += sha1-arm-neon.o
+obj-$(CONFIG_CRYPTO_SHA256_ARM) += sha256-arm.o
 obj-$(CONFIG_CRYPTO_SHA512_ARM_NEON) += sha512-arm-neon.o
 obj-$(CONFIG_CRYPTO_SHA1_ARM_CE) += sha1-arm-ce.o
 obj-$(CONFIG_CRYPTO_SHA2_ARM_CE) += sha2-arm-ce.o
@@ -16,6 +17,8 @@ aes-arm-y	:= aes-armv4.o aes_glue.o
 aes-arm-bs-y	:= aesbs-core.o aesbs-glue.o
 sha1-arm-y	:= sha1-armv4-large.o sha1_glue.o
 sha1-arm-neon-y	:= sha1-armv7-neon.o sha1_neon_glue.o
+sha256-arm-neon-$(CONFIG_KERNEL_MODE_NEON) := sha256_neon_glue.o
+sha256-arm-y	:= sha256-core.o sha256_glue.o $(sha256-arm-neon-y)
 sha512-arm-neon-y := sha512-armv7-neon.o sha512_neon_glue.o
 sha1-arm-ce-y	:= sha1-ce-core.o sha1-ce-glue.o
 sha2-arm-ce-y	:= sha2-ce-core.o sha2-ce-glue.o
@@ -28,4 +31,7 @@ quiet_cmd_perl = PERL    $@
 $(src)/aesbs-core.S_shipped: $(src)/bsaes-armv7.pl
 	$(call cmd,perl)
 
-.PRECIOUS: $(obj)/aesbs-core.S
+$(src)/sha256-core.S_shipped: $(src)/sha256-armv4.pl
+	$(call cmd,perl)
+
+.PRECIOUS: $(obj)/aesbs-core.S $(obj)/sha256-core.S
arch/arm/crypto/sha2-ce-glue.c +2 -2
index 9ffe8ad..0449eca 100644
@@ -163,7 +163,7 @@ static struct shash_alg algs[] = { {
 	.base			= {
 		.cra_name		= "sha224",
 		.cra_driver_name	= "sha224-ce",
-		.cra_priority		= 200,
+		.cra_priority		= 300,
 		.cra_flags		= CRYPTO_ALG_TYPE_SHASH,
 		.cra_blocksize		= SHA256_BLOCK_SIZE,
 		.cra_module		= THIS_MODULE,
@@ -180,7 +180,7 @@ static struct shash_alg algs[] = { {
 	.base			= {
 		.cra_name		= "sha256",
 		.cra_driver_name	= "sha256-ce",
-		.cra_priority		= 200,
+		.cra_priority		= 300,
 		.cra_flags		= CRYPTO_ALG_TYPE_SHASH,
 		.cra_blocksize		= SHA256_BLOCK_SIZE,
 		.cra_module		= THIS_MODULE,
arch/arm/crypto/sha256-armv4.pl new file +716 -0

716 lines not on this page · raw message

arch/arm/crypto/sha256-core.S_shipped new file +2808 -0

2,232 lines not on this page · raw message

arch/arm/crypto/sha256_glue.c new file +246 -0

246 lines not on this page · raw message

arch/arm/crypto/sha256_glue.h new file +23 -0
new file mode 100644
index 0000000..0312f4f

Lines of this file are not shown. View the raw message.

arch/arm/crypto/sha256_neon_glue.c new file +172 -0

172 lines not on this page · raw message

The rest of this diff is not shown. View the raw message.

Part of the diff is not shown here. View the raw message.

maintainer
#29 lore raw

PATCH v3 1/1 arm: crypto: Add optimized SHA-256/224

Quoted 8 lines · Sami Tolvanen

Add Andy Polyakov's optimized assembly and NEON implementations for SHA-256/224.

The sha256-armv4.pl script for generating the assembly code is from OpenSSL commit 51f8d095562f36cdaa6893597b5c609e943b0565.

Compared to sha256-generic these implementations have the following tcrypt speed improvements on Motorola Nexus 6 (Snapdragon 805):

I cannot merge this because none of your emails are making it to the mailing list so nobody except those on the cc list can see the patch.

Please refer to section 7 in Documentation/SubmittingPatches.

Thanks,

Signature · 3 lines
Email: Herbert Xu <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
maintainer
#31 lore raw

PATCH v3 1/1 arm: crypto: Add optimized SHA-256/224

Quoted 10 lines · Sami Tolvanen
Quoted 5 lines · Herbert Xu

I cannot merge this because none of your emails are making it to the mailing list so nobody except those on the cc list can see the patch.

Please refer to section 7 in Documentation/SubmittingPatches.

Please find a hosted version of the patch here:

https://raw.githubusercontent.com/samitolvanen/kernelpatches/master/sha256.v3.patch

Patch applied. Thanks!

Signature · 3 lines
Email: Herbert Xu <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
#32 lore raw

PATCH 1/1 arm: crypto: Add NEON optimized SHA-256

In reply to Sami Tolvanen
Quoted 3 lines · Sami Tolvanen

Add Andy Polyakov's NEON optimized SHA-256 implementation.

On Nexus 6, this implementation is ~2x faster than sha256-generic.

do you plan to add the sha512 from openssl too?

Whould be nice so armv4 can get faster implementatio too

Best Regards,
J.