Skip to contentSkip to conversation

RISC-V crypto with reworked asm files

RFC PATCH Superseded Eric Biggers 3 participants 21 messages Jan 2, 2024 – Jan 4, 2024

Subsystems (2)

v1 of 3 Superseded Latest is v3 →

lore
Share & tools
lore
#0 lore raw

cover RISC-V crypto with reworked asm files

As discussed previously, the proposed use of the so-called perlasm for the RISC-V crypto assembly files makes them difficult to read, and these files have some other issues such extensively duplicating source code for the different AES key lengths and for the unrolled hash functions. There is/was a desire to share code with OpenSSL, but many of the files have already diverged significantly; also, for most of the algorithms the source code can be quite short anyway, due to the native support for them in the RISC-V vector crypto extensions combined with the way the RISC-V vector extension naturally scales to arbitrary vector lengths.

Since we're still waiting for prerequisite patches to be merged anyway, we have a bit more time to get this cleaned up properly. So I've had a go at cleaning up the patchset to use standard .S files, with the code duplication fixed. I also made some tweaks to make the different algorithms consistent with each other and with what exists in the kernel already for other architectures, and tried to improve comments.

The result is this series, which passes all tests and is about 2400 lines shorter than the latest version with the perlasm
(https://lore.kernel.org/linux-crypto/[email protected]/).
All the same functionality and general optimizations are still included, except for some minor optimizations in XTS that I dropped since it's not clear they are worth the complexity. (Note that almost all users of XTS in the kernel only use it with block-aligned messages, so it's not very important to optimize the ciphertext stealing case.)

I'd appreciate people's thoughts on this series. Jerry, I hope I'm not stepping on your toes too much here, but I think there are some big improvements here.

This series is based on riscv/for-next
(https://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux.git/log/?h=for-next)
commit f352a28cc2fb4ee8d08c6a6362c9a861fcc84236, and for convenience I've included the prerequisite patches too.

Andy Chiu (1):
riscv: vector: make Vector always available for softirq context

Eric Biggers (1):
RISC-V: add TOOLCHAIN_HAS_VECTOR_CRYPTO

Greentime Hu (1):
riscv: Add support for kernel mode vector

Heiko Stuebner (2):
RISC-V: add helper function to read the vector VLEN
RISC-V: hook new crypto subdir into build-system

Jerry Shih (8):
crypto: riscv - add vector crypto accelerated AES
crypto: riscv - add vector crypto accelerated AES-{ECB,CBC,CTR,XTS}
crypto: riscv - add vector crypto accelerated ChaCha20
crypto: riscv - add vector crypto accelerated GHASH
crypto: riscv - add vector crypto accelerated SHA-{256,224}
crypto: riscv - add vector crypto accelerated SHA-{512,384}
crypto: riscv - add vector crypto accelerated SM3
crypto: riscv - add vector crypto accelerated SM4

 arch/riscv/Kbuild                             |   1 +
 arch/riscv/Kconfig                            |   7 +
 arch/riscv/crypto/Kconfig                     | 108 +++++
 arch/riscv/crypto/Makefile                    |  28 ++
 arch/riscv/crypto/aes-macros.S                | 156 +++++++
 .../crypto/aes-riscv64-block-mode-glue.c      | 435 ++++++++++++++++++
 arch/riscv/crypto/aes-riscv64-glue.c          | 123 +++++
 arch/riscv/crypto/aes-riscv64-glue.h          |  15 +
 .../crypto/aes-riscv64-zvkned-zvbb-zvkg.S     | 300 ++++++++++++
 arch/riscv/crypto/aes-riscv64-zvkned-zvkb.S   | 146 ++++++
 arch/riscv/crypto/aes-riscv64-zvkned.S        | 180 ++++++++
 arch/riscv/crypto/chacha-riscv64-glue.c       | 101 ++++
 arch/riscv/crypto/chacha-riscv64-zvkb.S       | 294 ++++++++++++
 arch/riscv/crypto/ghash-riscv64-glue.c        | 170 +++++++
 arch/riscv/crypto/ghash-riscv64-zvkg.S        |  72 +++
 arch/riscv/crypto/sha256-riscv64-glue.c       | 137 ++++++
 .../sha256-riscv64-zvknha_or_zvknhb-zvkb.S    | 225 +++++++++
 arch/riscv/crypto/sha512-riscv64-glue.c       | 133 ++++++
 .../riscv/crypto/sha512-riscv64-zvknhb-zvkb.S | 203 ++++++++
 arch/riscv/crypto/sm3-riscv64-glue.c          | 112 +++++
 arch/riscv/crypto/sm3-riscv64-zvksh-zvkb.S    | 123 +++++
 arch/riscv/crypto/sm4-riscv64-glue.c          | 109 +++++
 arch/riscv/crypto/sm4-riscv64-zvksed-zvkb.S   | 117 +++++
 arch/riscv/include/asm/processor.h            |  14 +-
 arch/riscv/include/asm/simd.h                 |  48 ++
 arch/riscv/include/asm/vector.h               |  20 +
 arch/riscv/kernel/Makefile                    |   1 +
 arch/riscv/kernel/kernel_mode_vector.c        | 126 +++++
 arch/riscv/kernel/process.c                   |   1 +
 crypto/Kconfig                                |   3 +
 30 files changed, 3507 insertions(+), 1 deletion(-)
 create mode 100644 arch/riscv/crypto/Kconfig
 create mode 100644 arch/riscv/crypto/Makefile
 create mode 100644 arch/riscv/crypto/aes-macros.S
 create mode 100644 arch/riscv/crypto/aes-riscv64-block-mode-glue.c
 create mode 100644 arch/riscv/crypto/aes-riscv64-glue.c
 create mode 100644 arch/riscv/crypto/aes-riscv64-glue.h
 create mode 100644 arch/riscv/crypto/aes-riscv64-zvkned-zvbb-zvkg.S
 create mode 100644 arch/riscv/crypto/aes-riscv64-zvkned-zvkb.S
 create mode 100644 arch/riscv/crypto/aes-riscv64-zvkned.S
 create mode 100644 arch/riscv/crypto/chacha-riscv64-glue.c
 create mode 100644 arch/riscv/crypto/chacha-riscv64-zvkb.S
 create mode 100644 arch/riscv/crypto/ghash-riscv64-glue.c
 create mode 100644 arch/riscv/crypto/ghash-riscv64-zvkg.S
 create mode 100644 arch/riscv/crypto/sha256-riscv64-glue.c
 create mode 100644 arch/riscv/crypto/sha256-riscv64-zvknha_or_zvknhb-zvkb.S
 create mode 100644 arch/riscv/crypto/sha512-riscv64-glue.c
 create mode 100644 arch/riscv/crypto/sha512-riscv64-zvknhb-zvkb.S
 create mode 100644 arch/riscv/crypto/sm3-riscv64-glue.c
 create mode 100644 arch/riscv/crypto/sm3-riscv64-zvksh-zvkb.S
 create mode 100644 arch/riscv/crypto/sm4-riscv64-glue.c
 create mode 100644 arch/riscv/crypto/sm4-riscv64-zvksed-zvkb.S
 create mode 100644 arch/riscv/include/asm/simd.h
 create mode 100644 arch/riscv/kernel/kernel_mode_vector.c

base-commit: f352a28cc2fb4ee8d08c6a6362c9a861fcc84236

Signature · 1 line
2.43.0
#1 lore raw

RFC PATCH 1/13 riscv: Add support for kernel mode vector

From: Greentime Hu <[email protected]>

Add kernel_vector_begin() and kernel_vector_end() function declarations and corresponding definitions in kernel_mode_vector.c

These are needed to wrap uses of vector in kernel mode.

---
 arch/riscv/include/asm/processor.h     |  13 ++-
 arch/riscv/include/asm/simd.h          |  44 ++++++++++
 arch/riscv/include/asm/vector.h        |   9 ++
 arch/riscv/kernel/Makefile             |   1 +
 arch/riscv/kernel/kernel_mode_vector.c | 116 +++++++++++++++++++++++++
 arch/riscv/kernel/process.c            |   1 +
 6 files changed, 183 insertions(+), 1 deletion(-)
 create mode 100644 arch/riscv/include/asm/simd.h
 create mode 100644 arch/riscv/kernel/kernel_mode_vector.c
arch/riscv/include/asm/processor.h +12 -1
index f19f861cda549..28d19aea24b1d 100644
@@ -66,29 +66,40 @@
 #define TASK_UNMAPPED_BASE	PAGE_ALIGN((UL(1) << MMAP_MIN_VA_BITS) / 3)
 #else
 #define TASK_UNMAPPED_BASE	PAGE_ALIGN(TASK_SIZE / 3)
 #endif
 
 #ifndef __ASSEMBLY__
 
 struct task_struct;
 struct pt_regs;
 
+/*
+ * We use a flag to track in-kernel Vector context. Currently the flag has the
+ * following meaning:
+ *
+ *  - bit 0: indicates whether the in-kernel Vector context is active. The
+ *    activation of this state disables the preemption. Currently only 0 and 1
+ *    are valid value for this field. Other values are reserved for future uses.
+ */
+#define RISCV_KERNEL_MODE_V	0x1
+
 /* CPU-specific state of a task */
 struct thread_struct {
 	/* Callee-saved registers */
 	unsigned long ra;
 	unsigned long sp;	/* Kernel mode stack */
 	unsigned long s[12];	/* s[0]: frame pointer */
 	struct __riscv_d_ext_state fstate;
 	unsigned long bad_cause;
-	unsigned long vstate_ctrl;
+	u32 riscv_v_flags;
+	u32 vstate_ctrl;
 	struct __riscv_v_ext_state vstate;
 	unsigned long align_ctl;
 };
 
 /* Whitelist the fstate from the task_struct for hardened usercopy */
 static inline void arch_thread_struct_whitelist(unsigned long *offset,
 						unsigned long *size)
 {
 	*offset = offsetof(struct thread_struct, fstate);
 	*size = sizeof_field(struct thread_struct, fstate);
arch/riscv/include/asm/simd.h new file +44 -0

44 lines not on this page · raw message

arch/riscv/include/asm/vector.h +9 -0
index 87aaef656257c..71af3404fda14 100644
@@ -15,20 +15,29 @@
 #include <linux/sched.h>
 #include <linux/sched/task_stack.h>
 #include <asm/ptrace.h>
 #include <asm/cpufeature.h>
 #include <asm/csr.h>
 #include <asm/asm.h>
 
 extern unsigned long riscv_v_vsize;
 int riscv_v_setup_vsize(void);
 bool riscv_v_first_use_handler(struct pt_regs *regs);
+void kernel_vector_begin(void);
+void kernel_vector_end(void);
+void get_cpu_vector_context(void);
+void put_cpu_vector_context(void);
+
+static inline u32 riscv_v_flags(void)
+{
+	return current->thread.riscv_v_flags;
+}
 
 static __always_inline bool has_vector(void)
 {
 	return riscv_has_extension_unlikely(RISCV_ISA_EXT_v);
 }
 
 static inline void __riscv_v_vstate_clean(struct pt_regs *regs)
 {
 	regs->status = (regs->status & ~SR_VS) | SR_VS_CLEAN;
 }
arch/riscv/kernel/Makefile +1 -0
index fee22a3d1b534..8c58595696b32 100644
@@ -56,20 +56,21 @@ obj-y	+= riscv_ksyms.o
 obj-y	+= stacktrace.o
 obj-y	+= cacheinfo.o
 obj-y	+= patch.o
 obj-y	+= probes/
 obj-y	+= tests/
 obj-$(CONFIG_MMU) += vdso.o vdso/
 
 obj-$(CONFIG_RISCV_MISALIGNED)	+= traps_misaligned.o
 obj-$(CONFIG_FPU)		+= fpu.o
 obj-$(CONFIG_RISCV_ISA_V)	+= vector.o
+obj-$(CONFIG_RISCV_ISA_V)	+= kernel_mode_vector.o
 obj-$(CONFIG_SMP)		+= smpboot.o
 obj-$(CONFIG_SMP)		+= smp.o
 obj-$(CONFIG_SMP)		+= cpu_ops.o
 
 obj-$(CONFIG_RISCV_BOOT_SPINWAIT) += cpu_ops_spinwait.o
 obj-$(CONFIG_MODULES)		+= module.o
 obj-$(CONFIG_MODULE_SECTIONS)	+= module-sections.o
 
 obj-$(CONFIG_CPU_PM)		+= suspend_entry.o suspend.o
 obj-$(CONFIG_HIBERNATION)	+= hibernate.o hibernate-asm.o
arch/riscv/kernel/kernel_mode_vector.c new file +116 -0

116 lines not on this page · raw message

arch/riscv/kernel/process.c +1 -0
index 4f21d970a1292..4a1275db11460 100644
@@ -214,14 +214,15 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
 		*childregs = *(current_pt_regs());
 		/* Turn off status.VS */
 		riscv_v_vstate_off(childregs);
 		if (usp) /* User fork */
 			childregs->sp = usp;
 		if (clone_flags & CLONE_SETTLS)
 			childregs->tp = tls;
 		childregs->a0 = 0; /* Return value of fork() */
 		p->thread.s[0] = 0;
 	}
+	p->thread.riscv_v_flags = 0;
 	p->thread.ra = (unsigned long)ret_from_fork;
 	p->thread.sp = (unsigned long)childregs; /* kernel sp */
 	return 0;
 }
Signature · 1 line
2.43.0
#2 lore raw

RFC PATCH 2/13 riscv: vector: make Vector always available for softirq context

In reply to Eric Biggers

From: Andy Chiu <[email protected]>

The goal of this patch is to provide full support of Vector in kernel softirq context. So that some of the crypto alogrithms won't need scalar fallbacks.

By disabling bottom halves in active kernel-mode Vector, softirq will not be able to nest on top of any kernel-mode Vector. So, softirq context is able to use Vector whenever it runs.

After this patch, Vector context cannot start with irqs disabled. Otherwise local_bh_enable() may run in a wrong context.

Disabling bh is not enough for RT-kernel to prevent preeemption. So we must disable preemption, which also implies disabling bh on RT.

Related-to: commit 696207d4258b ("arm64/sve: Make kernel FPU protection RT friendly")
Related-to: commit 66c3ec5a7120 ("arm64: neon: Forbid when irqs are disabled")

---
 arch/riscv/include/asm/processor.h     |  5 +++--
 arch/riscv/include/asm/simd.h          |  6 +++++-
 arch/riscv/kernel/kernel_mode_vector.c | 14 ++++++++++++--
 3 files changed, 20 insertions(+), 5 deletions(-)
arch/riscv/include/asm/processor.h +3 -2
index 28d19aea24b1d..e768397890673 100644
@@ -71,22 +71,23 @@
 #ifndef __ASSEMBLY__
 
 struct task_struct;
 struct pt_regs;
 
 /*
  * We use a flag to track in-kernel Vector context. Currently the flag has the
  * following meaning:
  *
  *  - bit 0: indicates whether the in-kernel Vector context is active. The
- *    activation of this state disables the preemption. Currently only 0 and 1
- *    are valid value for this field. Other values are reserved for future uses.
+ *    activation of this state disables the preemption. On a non-RT kernel, it
+ *    also disable bh. Currently only 0 and 1 are valid value for this field.
+ *    Other values are reserved for future uses.
  */
 #define RISCV_KERNEL_MODE_V	0x1
 
 /* CPU-specific state of a task */
 struct thread_struct {
 	/* Callee-saved registers */
 	unsigned long ra;
 	unsigned long sp;	/* Kernel mode stack */
 	unsigned long s[12];	/* s[0]: frame pointer */
 	struct __riscv_d_ext_state fstate;
arch/riscv/include/asm/simd.h +5 -1
index ef8af413a9fc7..4d699e16c9a96 100644
@@ -21,22 +21,26 @@
  *                instructions or access the vector register file
  *
  * Callers must not assume that the result remains true beyond the next
  * preempt_enable() or return from softirq context.
  */
 static __must_check inline bool may_use_simd(void)
 {
 	/*
 	 * RISCV_KERNEL_MODE_V is only set while preemption is disabled,
 	 * and is clear whenever preemption is enabled.
+	 *
+	 * Kernel-mode Vector temporarily disables bh. So we must not return
+	 * true on irq_disabled(). Otherwise we would fail the lockdep check
+	 * calling local_bh_enable()
 	 */
-	return !in_hardirq() && !in_nmi() && !(riscv_v_flags() & RISCV_KERNEL_MODE_V);
+	return !in_hardirq() && !in_nmi() && !irqs_disabled() && !(riscv_v_flags() & RISCV_KERNEL_MODE_V);
 }
 
 #else /* ! CONFIG_RISCV_ISA_V */
 
 static __must_check inline bool may_use_simd(void)
 {
 	return false;
 }
 
 #endif /* ! CONFIG_RISCV_ISA_V */
arch/riscv/kernel/kernel_mode_vector.c +12 -2
index 114cf4f0a0eb6..2fc145edae3dd 100644
@@ -39,37 +39,47 @@ static inline void riscv_v_stop(u32 flags)
 }
 
 /*
  * Claim ownership of the CPU vector context for use by the calling context.
  *
  * The caller may freely manipulate the vector context metadata until
  * put_cpu_vector_context() is called.
  */
 void get_cpu_vector_context(void)
 {
-	preempt_disable();
+	/*
+	 * disable softirqs so it is impossible for softirqs to nest
+	 * get_cpu_vector_context() when kernel is actively using Vector.
+	 */
+	if (!IS_ENABLED(CONFIG_PREEMPT_RT))
+		local_bh_disable();
+	else
+		preempt_disable();
 
 	riscv_v_start(RISCV_KERNEL_MODE_V);
 }
 
 /*
  * Release the CPU vector context.
  *
  * Must be called from a context in which get_cpu_vector_context() was
  * previously called, with no call to put_cpu_vector_context() in the
  * meantime.
  */
 void put_cpu_vector_context(void)
 {
 	riscv_v_stop(RISCV_KERNEL_MODE_V);
 
-	preempt_enable();
+	if (!IS_ENABLED(CONFIG_PREEMPT_RT))
+		local_bh_enable();
+	else
+		preempt_enable();
 }
 
 /*
  * kernel_vector_begin(): obtain the CPU vector registers for use by the calling
  * context
  *
  * Must not be called unless may_use_simd() returns true.
  * Task context in the vector registers is saved back to memory as necessary.
  *
  * A matching call to kernel_vector_end() must be made before returning from the
Signature · 1 line
2.43.0
#3 lore raw

RFC PATCH 3/13 RISC-V: add helper function to read the vector VLEN

In reply to Eric Biggers

From: Heiko Stuebner <[email protected]>

VLEN describes the length of each vector register and some instructions need specific minimal VLENs to work correctly.

The vector code already includes a variable riscv_v_vsize that contains the value of "32 vector registers with vlenb length" that gets filled during boot. vlenb is the value contained in the CSR_VLENB register and the value represents "VLEN / 8".

So add riscv_vector_vlen() to return the actual VLEN value for in-kernel users when they need to check the available VLEN.

---
 arch/riscv/include/asm/vector.h | 11 +++++++++++
 1 file changed, 11 insertions(+)
arch/riscv/include/asm/vector.h +11 -0
index 71af3404fda14..ae724e016fe24 100644
@@ -218,11 +218,22 @@ static inline bool riscv_v_vstate_ctrl_user_allowed(void) { return false; }
 #define riscv_v_vsize (0)
 #define riscv_v_vstate_discard(regs)		do {} while (0)
 #define riscv_v_vstate_save(task, regs)		do {} while (0)
 #define riscv_v_vstate_restore(task, regs)	do {} while (0)
 #define __switch_to_vector(__prev, __next)	do {} while (0)
 #define riscv_v_vstate_off(regs)		do {} while (0)
 #define riscv_v_vstate_on(regs)			do {} while (0)
 
 #endif /* CONFIG_RISCV_ISA_V */
 
+/*
+ * Return the implementation's vlen value.
+ *
+ * riscv_v_vsize contains the value of "32 vector registers with vlenb length"
+ * so rebuild the vlen value in bits from it.
+ */
+static inline int riscv_vector_vlen(void)
+{
+	return riscv_v_vsize / 32 * 8;
+}
+
 #endif /* ! __ASM_RISCV_VECTOR_H */
Signature · 1 line
2.43.0
#4 lore raw

RFC PATCH 4/13 RISC-V: add TOOLCHAIN_HAS_VECTOR_CRYPTO

In reply to Eric Biggers

From: Eric Biggers <[email protected]>

Add a kconfig symbol that indicates whether the toolchain supports the vector crypto extensions. This is needed by the RISC-V crypto code.

---
 arch/riscv/Kconfig | 7 +++++++
 1 file changed, 7 insertions(+)
arch/riscv/Kconfig +7 -0
index 95a2a06acc6a6..bf275a713b1b5 100644
@@ -526,20 +526,27 @@ config RISCV_ISA_V_DEFAULT_ENABLE
 	  If you don't know what to do here, say Y.
 
 config TOOLCHAIN_HAS_ZBB
 	bool
 	default y
 	depends on !64BIT || $(cc-option,-mabi=lp64 -march=rv64ima_zbb)
 	depends on !32BIT || $(cc-option,-mabi=ilp32 -march=rv32ima_zbb)
 	depends on LLD_VERSION >= 150000 || LD_VERSION >= 23900
 	depends on AS_HAS_OPTION_ARCH
 
+# This symbol indicates that the toolchain supports all v1.0 vector crypto
+# extensions, including Zvk*, Zvbb, and Zvbc.  LLVM added all of these at once.
+# binutils added all except Zvkb, then added Zvkb.  So we just check for Zvkb.
+config TOOLCHAIN_HAS_VECTOR_CRYPTO
+	def_bool $(as-instr, .option arch$(comma) +zvkb)
+	depends on AS_HAS_OPTION_ARCH
+
 config RISCV_ISA_ZBB
 	bool "Zbb extension support for bit manipulation instructions"
 	depends on TOOLCHAIN_HAS_ZBB
 	depends on MMU
 	depends on RISCV_ALTERNATIVE
 	default y
 	help
 	   Adds support to dynamically detect the presence of the ZBB
 	   extension (basic bit manipulation) and enable its usage.
 
Signature · 1 line
2.43.0
#5 lore raw

RFC PATCH 5/13 RISC-V: hook new crypto subdir into build-system

In reply to Eric Biggers

From: Heiko Stuebner <[email protected]>

Create a crypto subdirectory for added accelerated cryptography routines and hook it into the riscv Kbuild and the main crypto Kconfig.

---
 arch/riscv/Kbuild          | 1 +
 arch/riscv/crypto/Kconfig  | 5 +++++
 arch/riscv/crypto/Makefile | 4 ++++
 crypto/Kconfig             | 3 +++
 4 files changed, 13 insertions(+)
 create mode 100644 arch/riscv/crypto/Kconfig
 create mode 100644 arch/riscv/crypto/Makefile
arch/riscv/Kbuild +1 -0
index d25ad1c19f881..2c585f7a0b6ef 100644
@@ -1,11 +1,12 @@
 # SPDX-License-Identifier: GPL-2.0-only
 
 obj-y += kernel/ mm/ net/
 obj-$(CONFIG_BUILTIN_DTB) += boot/dts/
+obj-$(CONFIG_CRYPTO) += crypto/
 obj-y += errata/
 obj-$(CONFIG_KVM) += kvm/
 
 obj-$(CONFIG_ARCH_SUPPORTS_KEXEC_PURGATORY) += purgatory/
 
 # for cleaning
 subdir- += boot
arch/riscv/crypto/Kconfig new file +5 -0
new file mode 100644
index 0000000000000..10d60edc0110a
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+
+menu "Accelerated Cryptographic Algorithms for CPU (riscv)"
+
+endmenu
arch/riscv/crypto/Makefile new file +4 -0
new file mode 100644
index 0000000000000..b3b6332c9f6d0
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# linux/arch/riscv/crypto/Makefile
+#
crypto/Kconfig +3 -0
index 70661f58ee41c..c8fd2b83e589b 100644
@@ -1512,20 +1512,23 @@ source "arch/arm64/crypto/Kconfig"
 endif
 if LOONGARCH
 source "arch/loongarch/crypto/Kconfig"
 endif
 if MIPS
 source "arch/mips/crypto/Kconfig"
 endif
 if PPC
 source "arch/powerpc/crypto/Kconfig"
 endif
+if RISCV
+source "arch/riscv/crypto/Kconfig"
+endif
 if S390
 source "arch/s390/crypto/Kconfig"
 endif
 if SPARC
 source "arch/sparc/crypto/Kconfig"
 endif
 if X86
 source "arch/x86/crypto/Kconfig"
 endif
 endif
Signature · 1 line
2.43.0
#6 lore raw

RFC PATCH 6/13 crypto: riscv - add vector crypto accelerated AES

In reply to Eric Biggers

From: Jerry Shih <[email protected]>

Add an implementation of AES using the Zvkned extension. The assembly code is derived from OpenSSL code (openssl/openssl#21923) that was dual-licensed so that it could be reused in the kernel. Nevertheless, the assembly has been significantly reworked for integration with the kernel, for example by using a regular .S file instead of the so-called perlasm, using the assembler instead of bare '.inst', greatly reducing code duplication, supporting AES-192, and making the code use the same AES key structure as the C code.

---
 arch/riscv/crypto/Kconfig              |  11 ++
 arch/riscv/crypto/Makefile             |   3 +
 arch/riscv/crypto/aes-macros.S         | 156 +++++++++++++++++++++++++
 arch/riscv/crypto/aes-riscv64-glue.c   | 123 +++++++++++++++++++
 arch/riscv/crypto/aes-riscv64-glue.h   |  15 +++
 arch/riscv/crypto/aes-riscv64-zvkned.S |  84 +++++++++++++
 6 files changed, 392 insertions(+)
 create mode 100644 arch/riscv/crypto/aes-macros.S
 create mode 100644 arch/riscv/crypto/aes-riscv64-glue.c
 create mode 100644 arch/riscv/crypto/aes-riscv64-glue.h
 create mode 100644 arch/riscv/crypto/aes-riscv64-zvkned.S
arch/riscv/crypto/Kconfig +11 -0
index 10d60edc0110a..2a7c365f2a86c 100644
@@ -1,5 +1,16 @@
 # SPDX-License-Identifier: GPL-2.0
 
 menu "Accelerated Cryptographic Algorithms for CPU (riscv)"
 
+config CRYPTO_AES_RISCV64
+	tristate "Ciphers: AES"
+	depends on 64BIT && RISCV_ISA_V && TOOLCHAIN_HAS_VECTOR_CRYPTO
+	select CRYPTO_ALGAPI
+	select CRYPTO_LIB_AES
+	help
+	  Block ciphers: AES cipher algorithms (FIPS-197)
+
+	  Architecture: riscv64 using:
+	  - Zvkned vector crypto extension
+
 endmenu
arch/riscv/crypto/Makefile +3 -0
index b3b6332c9f6d0..dca698c5cba3e 100644
@@ -1,4 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0-only
 #
 # linux/arch/riscv/crypto/Makefile
 #
+
+obj-$(CONFIG_CRYPTO_AES_RISCV64) += aes-riscv64.o
+aes-riscv64-y := aes-riscv64-glue.o aes-riscv64-zvkned.o
arch/riscv/crypto/aes-macros.S new file +156 -0

156 lines not on this page · raw message

arch/riscv/crypto/aes-riscv64-glue.c new file +123 -0

123 lines not on this page · raw message

arch/riscv/crypto/aes-riscv64-glue.h new file +15 -0
new file mode 100644
index 0000000000000..0d38613380784
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef AES_RISCV64_GLUE_H
+#define AES_RISCV64_GLUE_H
+
+#include <crypto/aes.h>
+#include <linux/types.h>
+
+int __riscv64_aes_setkey(struct crypto_aes_ctx *ctx,
+			 const u8 *key, unsigned int keylen);
+
+void __riscv64_aes_encrypt(const struct crypto_aes_ctx *ctx,
+			   u8 *dst, const u8 *src);
+
+#endif /* AES_RISCV64_GLUE_H */
arch/riscv/crypto/aes-riscv64-zvkned.S new file +84 -0

84 lines not on this page · raw message

Signature · 1 line
2.43.0
#7 lore raw

RFC PATCH 7/13 crypto: riscv - add vector crypto accelerated AES-{ECB,CBC,CTR,XTS}

In reply to Eric Biggers

From: Jerry Shih <[email protected]>

Add implementations of AES-ECB, AES-CBC, AES-CTR, and AES-XTS using the RISC-V vector crypto extensions. The assembly code is derived from OpenSSL code (openssl/openssl#21923) that was dual-licensed so that it could be reused in the kernel. Nevertheless, the assembly has been significantly reworked for integration with the kernel, for example by using regular .S files instead of the so-called perlasm, using the assembler instead of bare '.inst', greatly reducing code duplication, supporting AES-192, and making the code use the same AES key structure as the C code.

---
 arch/riscv/crypto/Kconfig                     |  20 +
 arch/riscv/crypto/Makefile                    |   3 +
 .../crypto/aes-riscv64-block-mode-glue.c      | 435 ++++++++++++++++++
 .../crypto/aes-riscv64-zvkned-zvbb-zvkg.S     | 300 ++++++++++++
 arch/riscv/crypto/aes-riscv64-zvkned-zvkb.S   | 146 ++++++
 arch/riscv/crypto/aes-riscv64-zvkned.S        |  96 ++++
 6 files changed, 1000 insertions(+)
 create mode 100644 arch/riscv/crypto/aes-riscv64-block-mode-glue.c
 create mode 100644 arch/riscv/crypto/aes-riscv64-zvkned-zvbb-zvkg.S
 create mode 100644 arch/riscv/crypto/aes-riscv64-zvkned-zvkb.S
arch/riscv/crypto/Kconfig +20 -0
index 2a7c365f2a86c..db8a5bcbea785 100644
@@ -6,11 +6,31 @@ config CRYPTO_AES_RISCV64
 	tristate "Ciphers: AES"
 	depends on 64BIT && RISCV_ISA_V && TOOLCHAIN_HAS_VECTOR_CRYPTO
 	select CRYPTO_ALGAPI
 	select CRYPTO_LIB_AES
 	help
 	  Block ciphers: AES cipher algorithms (FIPS-197)
 
 	  Architecture: riscv64 using:
 	  - Zvkned vector crypto extension
 
+config CRYPTO_AES_BLOCK_RISCV64
+	tristate "Ciphers: AES, modes: ECB/CBC/CTR/XTS"
+	depends on 64BIT && RISCV_ISA_V && TOOLCHAIN_HAS_VECTOR_CRYPTO
+	select CRYPTO_AES_RISCV64
+	select CRYPTO_SKCIPHER
+	help
+	  Length-preserving ciphers: AES cipher algorithms (FIPS-197)
+	  with block cipher modes:
+	  - ECB (Electronic Codebook) mode (NIST SP 800-38A)
+	  - CBC (Cipher Block Chaining) mode (NIST SP 800-38A)
+	  - CTR (Counter) mode (NIST SP 800-38A)
+	  - XTS (XOR Encrypt XOR Tweakable Block Cipher with Ciphertext
+	    Stealing) mode (NIST SP 800-38E and IEEE 1619)
+
+	  Architecture: riscv64 using:
+	  - Zvkned vector crypto extension
+	  - Zvbb vector extension (XTS)
+	  - Zvkb vector crypto extension (CTR/XTS)
+	  - Zvkg vector crypto extension (XTS)
+
 endmenu
arch/riscv/crypto/Makefile +3 -0
index dca698c5cba3e..5dd91f34f0d52 100644
@@ -1,7 +1,10 @@
 # SPDX-License-Identifier: GPL-2.0-only
 #
 # linux/arch/riscv/crypto/Makefile
 #
 
 obj-$(CONFIG_CRYPTO_AES_RISCV64) += aes-riscv64.o
 aes-riscv64-y := aes-riscv64-glue.o aes-riscv64-zvkned.o
+
+obj-$(CONFIG_CRYPTO_AES_BLOCK_RISCV64) += aes-block-riscv64.o
+aes-block-riscv64-y := aes-riscv64-block-mode-glue.o aes-riscv64-zvkned-zvbb-zvkg.o aes-riscv64-zvkned-zvkb.o
arch/riscv/crypto/aes-riscv64-block-mode-glue.c new file +435 -0

435 lines not on this page · raw message

arch/riscv/crypto/aes-riscv64-zvkned-zvbb-zvkg.S new file +300 -0

300 lines not on this page · raw message

arch/riscv/crypto/aes-riscv64-zvkned-zvkb.S new file +146 -0

146 lines not on this page · raw message

arch/riscv/crypto/aes-riscv64-zvkned.S +96 -0

106 lines not on this page · raw message

Signature · 1 line
2.43.0
#8 lore raw

Re: [RFC PATCH 07/13] crypto: riscv - add vector crypto accelerated AES-{ECB,CBC,CTR,XTS}

Quoted 5 lines · Eric Biggers
arch/riscv/crypto/Makefile +0 -0
index dca698c5cba3e..5dd91f34f0d52 100644

arch/riscv/crypto/Makefile line 10

Quoted 10 lines
arch/riscv/crypto/Makefile +3 -0
@@ -1,7 +1,10 @@
 # SPDX-License-Identifier: GPL-2.0-only
 #
 # linux/arch/riscv/crypto/Makefile
 #
 
 obj-$(CONFIG_CRYPTO_AES_RISCV64) += aes-riscv64.o
 aes-riscv64-y := aes-riscv64-glue.o aes-riscv64-zvkned.o
+
+obj-$(CONFIG_CRYPTO_AES_BLOCK_RISCV64) += aes-block-riscv64.o
+aes-block-riscv64-y := aes-riscv64-block-mode-glue.o aes-riscv64-zvkned-zvbb-zvkg.o aes-riscv64-zvkned-zvkb.o

A bug I noticed (which is also present in Jerry's patchset) is that some of the code of the aes-block-riscv64 module is located in aes-riscv64-zvkned.S, which isn't built into that module but rather into aes-riscv64. This causes a build error when both CONFIG_CRYPTO_AES_RISCV64 and CONFIG_CRYPTO_AES_BLOCK_RISCV64 are set to 'm':

ERROR: modpost: "aes_cbc_decrypt_zvkned" [arch/riscv/crypto/aes-block-riscv64.ko] undefined!
ERROR: modpost: "aes_ecb_decrypt_zvkned" [arch/riscv/crypto/aes-block-riscv64.ko] undefined!
ERROR: modpost: "aes_cbc_encrypt_zvkned" [arch/riscv/crypto/aes-block-riscv64.ko] undefined!
ERROR: modpost: "aes_ecb_encrypt_zvkned" [arch/riscv/crypto/aes-block-riscv64.ko] undefined!

To fix this, I think we should just merge the two modules and kconfig options together so that there is one module that provides both the AES modes and the AES single-block cipher. That's how x86's aesni-intel works, for example.

- Eric

#9 lore raw

Re: [RFC PATCH 07/13] crypto: riscv - add vector crypto accelerated AES-{ECB,CBC,CTR,XTS}

Quoted 28 lines · Eric Biggers
Quoted 12 lines · Eric Biggers
arch/riscv/crypto/Makefile +0 -0
index dca698c5cba3e..5dd91f34f0d52 100644
@@ -1,7 +1,10 @@
 # SPDX-License-Identifier: GPL-2.0-only
 #
 # linux/arch/riscv/crypto/Makefile
 #
 

obj-$(CONFIG_CRYPTO_AES_RISCV64) += aes-riscv64.o aes-riscv64-y := aes-riscv64-glue.o aes-riscv64-zvkned.o

arch/riscv/crypto/Makefile line 10

Quoted 3 lines
arch/riscv/crypto/Makefile +3 -0
+
+obj-$(CONFIG_CRYPTO_AES_BLOCK_RISCV64) += aes-block-riscv64.o
+aes-block-riscv64-y := aes-riscv64-block-mode-glue.o aes-riscv64-zvkned-zvbb-zvkg.o aes-riscv64-zvkned-zvkb.o

A bug I noticed (which is also present in Jerry's patchset) is that some of the code of the aes-block-riscv64 module is located in aes-riscv64-zvkned.S, which isn't built into that module but rather into aes-riscv64. This causes a build error when both CONFIG_CRYPTO_AES_RISCV64 and CONFIG_CRYPTO_AES_BLOCK_RISCV64 are set to 'm':

ERROR: modpost: "aes_cbc_decrypt_zvkned" [arch/riscv/crypto/aes-block-riscv64.ko] undefined!
ERROR: modpost: "aes_ecb_decrypt_zvkned" [arch/riscv/crypto/aes-block-riscv64.ko] undefined!
ERROR: modpost: "aes_cbc_encrypt_zvkned" [arch/riscv/crypto/aes-block-riscv64.ko] undefined!
ERROR: modpost: "aes_ecb_encrypt_zvkned" [arch/riscv/crypto/aes-block-riscv64.ko] undefined!

Quoted 5 lines

To fix this, I think we should just merge the two modules and kconfig options together so that there is one module that provides both the AES modes and the AES single-block cipher. That's how x86's aesni-intel works, for example.

- Eric

That's a bug in my patchset.
I don't test with all options with M settings since I can't boot to qemu with all M settings.

Could we move the cbc and ecb from aes-riscv64-zvkned to aes-block-riscv64 instead of merging these two modules?
Thus, we could still enable the single aes block cipher without other extensions(e.g. zvbb or zvkg).

-Jerry

#10 lore raw

Re: [RFC PATCH 07/13] crypto: riscv - add vector crypto accelerated AES-{ECB,CBC,CTR,XTS}

Quoted 33 lines · Jerry Shih
Quoted 32 lines · Eric Biggers
Quoted 12 lines · Eric Biggers
arch/riscv/crypto/Makefile +0 -0
index dca698c5cba3e..5dd91f34f0d52 100644
@@ -1,7 +1,10 @@
 # SPDX-License-Identifier: GPL-2.0-only
 #
 # linux/arch/riscv/crypto/Makefile
 #
 

obj-$(CONFIG_CRYPTO_AES_RISCV64) += aes-riscv64.o aes-riscv64-y := aes-riscv64-glue.o aes-riscv64-zvkned.o

arch/riscv/crypto/Makefile line 10

Quoted 3 lines
arch/riscv/crypto/Makefile +3 -0
+
+obj-$(CONFIG_CRYPTO_AES_BLOCK_RISCV64) += aes-block-riscv64.o
+aes-block-riscv64-y := aes-riscv64-block-mode-glue.o aes-riscv64-zvkned-zvbb-zvkg.o aes-riscv64-zvkned-zvkb.o

A bug I noticed (which is also present in Jerry's patchset) is that some of the code of the aes-block-riscv64 module is located in aes-riscv64-zvkned.S, which isn't built into that module but rather into aes-riscv64. This causes a build error when both CONFIG_CRYPTO_AES_RISCV64 and CONFIG_CRYPTO_AES_BLOCK_RISCV64 are set to 'm':

ERROR: modpost: "aes_cbc_decrypt_zvkned" [arch/riscv/crypto/aes-block-riscv64.ko] undefined!
ERROR: modpost: "aes_ecb_decrypt_zvkned" [arch/riscv/crypto/aes-block-riscv64.ko] undefined!
ERROR: modpost: "aes_cbc_encrypt_zvkned" [arch/riscv/crypto/aes-block-riscv64.ko] undefined!
ERROR: modpost: "aes_ecb_encrypt_zvkned" [arch/riscv/crypto/aes-block-riscv64.ko] undefined!

To fix this, I think we should just merge the two modules and kconfig options together so that there is one module that provides both the AES modes and the AES single-block cipher. That's how x86's aesni-intel works, for example.

Quoted 8 lines
Quoted 1 line

- Eric

That's a bug in my patchset.
I don't test with all options with M settings since I can't boot to qemu with all M settings.

Could we move the cbc and ecb from aes-riscv64-zvkned to aes-block-riscv64 instead of merging these two modules?
Thus, we could still enable the single aes block cipher without other extensions(e.g. zvbb or zvkg).

My proposal to merge the two modules still results in the single-block AES cipher being registered when zvkned alone is present. It just won't be selectable separately via kconfig. I think that's fine.

- Eric

#11 lore raw

RFC PATCH 8/13 crypto: riscv - add vector crypto accelerated ChaCha20

In reply to Eric Biggers

From: Jerry Shih <[email protected]>

Add an implementation of ChaCha20 using the Zvkb extension. The assembly code is derived from OpenSSL code (openssl/openssl#21923) that was dual-licensed so that it could be reused in the kernel. Nevertheless, the assembly has been significantly reworked for integration with the kernel, for example by using a regular .S file instead of the so-called perlasm, using the assembler instead of bare '.inst', and reducing code duplication.

---
 arch/riscv/crypto/Kconfig               |  11 +
 arch/riscv/crypto/Makefile              |   3 +
 arch/riscv/crypto/chacha-riscv64-glue.c | 101 ++++++++
 arch/riscv/crypto/chacha-riscv64-zvkb.S | 294 ++++++++++++++++++++++++
 4 files changed, 409 insertions(+)
 create mode 100644 arch/riscv/crypto/chacha-riscv64-glue.c
 create mode 100644 arch/riscv/crypto/chacha-riscv64-zvkb.S
arch/riscv/crypto/Kconfig +11 -0
index db8a5bcbea785..d9a6920df9e99 100644
@@ -26,11 +26,22 @@ config CRYPTO_AES_BLOCK_RISCV64
 	  - CTR (Counter) mode (NIST SP 800-38A)
 	  - XTS (XOR Encrypt XOR Tweakable Block Cipher with Ciphertext
 	    Stealing) mode (NIST SP 800-38E and IEEE 1619)
 
 	  Architecture: riscv64 using:
 	  - Zvkned vector crypto extension
 	  - Zvbb vector extension (XTS)
 	  - Zvkb vector crypto extension (CTR/XTS)
 	  - Zvkg vector crypto extension (XTS)
 
+config CRYPTO_CHACHA_RISCV64
+	tristate "Ciphers: ChaCha"
+	depends on 64BIT && RISCV_ISA_V && TOOLCHAIN_HAS_VECTOR_CRYPTO
+	select CRYPTO_SKCIPHER
+	select CRYPTO_LIB_CHACHA_GENERIC
+	help
+	  Length-preserving ciphers: ChaCha20 stream cipher algorithm
+
+	  Architecture: riscv64 using:
+	  - Zvkb vector crypto extension
+
 endmenu
arch/riscv/crypto/Makefile +3 -0
index 5dd91f34f0d52..7b1e3a3f2041f 100644
@@ -1,10 +1,13 @@
 # SPDX-License-Identifier: GPL-2.0-only
 #
 # linux/arch/riscv/crypto/Makefile
 #
 
 obj-$(CONFIG_CRYPTO_AES_RISCV64) += aes-riscv64.o
 aes-riscv64-y := aes-riscv64-glue.o aes-riscv64-zvkned.o
 
 obj-$(CONFIG_CRYPTO_AES_BLOCK_RISCV64) += aes-block-riscv64.o
 aes-block-riscv64-y := aes-riscv64-block-mode-glue.o aes-riscv64-zvkned-zvbb-zvkg.o aes-riscv64-zvkned-zvkb.o
+
+obj-$(CONFIG_CRYPTO_CHACHA_RISCV64) += chacha-riscv64.o
+chacha-riscv64-y := chacha-riscv64-glue.o chacha-riscv64-zvkb.o
arch/riscv/crypto/chacha-riscv64-glue.c new file +101 -0

101 lines not on this page · raw message

arch/riscv/crypto/chacha-riscv64-zvkb.S new file +294 -0

294 lines not on this page · raw message

Signature · 1 line
2.43.0
#12 lore raw

RFC PATCH 9/13 crypto: riscv - add vector crypto accelerated GHASH

In reply to Eric Biggers

From: Jerry Shih <[email protected]>

Add an implementation of GHASH using the zvkg extension. The assembly code is derived from OpenSSL code (openssl/openssl#21923) that was dual-licensed so that it could be reused in the kernel. Nevertheless, the assembly has been significantly reworked for integration with the kernel, for example by using a regular .S file instead of the so-called perlasm, using the assembler instead of bare '.inst', reducing code duplication, and eliminating unnecessary endianness conversions.

---
 arch/riscv/crypto/Kconfig              |  10 ++
 arch/riscv/crypto/Makefile             |   3 +
 arch/riscv/crypto/ghash-riscv64-glue.c | 170 +++++++++++++++++++++++++
 arch/riscv/crypto/ghash-riscv64-zvkg.S |  72 +++++++++++
 4 files changed, 255 insertions(+)
 create mode 100644 arch/riscv/crypto/ghash-riscv64-glue.c
 create mode 100644 arch/riscv/crypto/ghash-riscv64-zvkg.S
arch/riscv/crypto/Kconfig +10 -0
index d9a6920df9e99..573818bb3e677 100644
@@ -37,11 +37,21 @@ config CRYPTO_CHACHA_RISCV64
 	tristate "Ciphers: ChaCha"
 	depends on 64BIT && RISCV_ISA_V && TOOLCHAIN_HAS_VECTOR_CRYPTO
 	select CRYPTO_SKCIPHER
 	select CRYPTO_LIB_CHACHA_GENERIC
 	help
 	  Length-preserving ciphers: ChaCha20 stream cipher algorithm
 
 	  Architecture: riscv64 using:
 	  - Zvkb vector crypto extension
 
+config CRYPTO_GHASH_RISCV64
+	tristate "Hash functions: GHASH"
+	depends on 64BIT && RISCV_ISA_V && TOOLCHAIN_HAS_VECTOR_CRYPTO
+	select CRYPTO_GCM
+	help
+	  GCM GHASH function (NIST SP 800-38D)
+
+	  Architecture: riscv64 using:
+	  - Zvkg vector crypto extension
+
 endmenu
arch/riscv/crypto/Makefile +3 -0
index 7b1e3a3f2041f..d21d3a3fc157c 100644
@@ -4,10 +4,13 @@
 #
 
 obj-$(CONFIG_CRYPTO_AES_RISCV64) += aes-riscv64.o
 aes-riscv64-y := aes-riscv64-glue.o aes-riscv64-zvkned.o
 
 obj-$(CONFIG_CRYPTO_AES_BLOCK_RISCV64) += aes-block-riscv64.o
 aes-block-riscv64-y := aes-riscv64-block-mode-glue.o aes-riscv64-zvkned-zvbb-zvkg.o aes-riscv64-zvkned-zvkb.o
 
 obj-$(CONFIG_CRYPTO_CHACHA_RISCV64) += chacha-riscv64.o
 chacha-riscv64-y := chacha-riscv64-glue.o chacha-riscv64-zvkb.o
+
+obj-$(CONFIG_CRYPTO_GHASH_RISCV64) += ghash-riscv64.o
+ghash-riscv64-y := ghash-riscv64-glue.o ghash-riscv64-zvkg.o
arch/riscv/crypto/ghash-riscv64-glue.c new file +170 -0

170 lines not on this page · raw message

arch/riscv/crypto/ghash-riscv64-zvkg.S new file +72 -0

72 lines not on this page · raw message

Signature · 1 line
2.43.0
#13 lore raw

RFC PATCH 10/13 crypto: riscv - add vector crypto accelerated SHA-{256,224}

In reply to Eric Biggers

From: Jerry Shih <[email protected]>

Add an implementation of SHA-224 and SHA-256 using the Zvknha or Zvknhb extension. The assembly code is derived from OpenSSL code (openssl/openssl#21923) that was dual-licensed so that it could be reused in the kernel. Nevertheless, the assembly has been significantly reworked for integration with the kernel, for example by using a regular .S file instead of the so-called perlasm, using the assembler instead of bare '.inst', and greatly reducing code duplication.

---
 arch/riscv/crypto/Kconfig                     |  11 +
 arch/riscv/crypto/Makefile                    |   3 +
 arch/riscv/crypto/sha256-riscv64-glue.c       | 137 +++++++++++
 .../sha256-riscv64-zvknha_or_zvknhb-zvkb.S    | 225 ++++++++++++++++++
 4 files changed, 376 insertions(+)
 create mode 100644 arch/riscv/crypto/sha256-riscv64-glue.c
 create mode 100644 arch/riscv/crypto/sha256-riscv64-zvknha_or_zvknhb-zvkb.S
arch/riscv/crypto/Kconfig +11 -0
index 573818bb3e677..533bc6def123a 100644
@@ -47,11 +47,22 @@ config CRYPTO_CHACHA_RISCV64
 config CRYPTO_GHASH_RISCV64
 	tristate "Hash functions: GHASH"
 	depends on 64BIT && RISCV_ISA_V && TOOLCHAIN_HAS_VECTOR_CRYPTO
 	select CRYPTO_GCM
 	help
 	  GCM GHASH function (NIST SP 800-38D)
 
 	  Architecture: riscv64 using:
 	  - Zvkg vector crypto extension
 
+config CRYPTO_SHA256_RISCV64
+	tristate "Hash functions: SHA-224 and SHA-256"
+	depends on 64BIT && RISCV_ISA_V && TOOLCHAIN_HAS_VECTOR_CRYPTO
+	select CRYPTO_SHA256
+	help
+	  SHA-224 and SHA-256 secure hash algorithm (FIPS 180)
+
+	  Architecture: riscv64 using:
+	  - Zvknha or Zvknhb vector crypto extensions
+	  - Zvkb vector crypto extension
+
 endmenu
arch/riscv/crypto/Makefile +3 -0
index d21d3a3fc157c..28a58e89927ae 100644
@@ -7,10 +7,13 @@ obj-$(CONFIG_CRYPTO_AES_RISCV64) += aes-riscv64.o
 aes-riscv64-y := aes-riscv64-glue.o aes-riscv64-zvkned.o
 
 obj-$(CONFIG_CRYPTO_AES_BLOCK_RISCV64) += aes-block-riscv64.o
 aes-block-riscv64-y := aes-riscv64-block-mode-glue.o aes-riscv64-zvkned-zvbb-zvkg.o aes-riscv64-zvkned-zvkb.o
 
 obj-$(CONFIG_CRYPTO_CHACHA_RISCV64) += chacha-riscv64.o
 chacha-riscv64-y := chacha-riscv64-glue.o chacha-riscv64-zvkb.o
 
 obj-$(CONFIG_CRYPTO_GHASH_RISCV64) += ghash-riscv64.o
 ghash-riscv64-y := ghash-riscv64-glue.o ghash-riscv64-zvkg.o
+
+obj-$(CONFIG_CRYPTO_SHA256_RISCV64) += sha256-riscv64.o
+sha256-riscv64-y := sha256-riscv64-glue.o sha256-riscv64-zvknha_or_zvknhb-zvkb.o
arch/riscv/crypto/sha256-riscv64-glue.c new file +137 -0

137 lines not on this page · raw message

arch/riscv/crypto/sha256-riscv64-zvknha_or_zvknhb-zvkb.S new file +225 -0

225 lines not on this page · raw message

Signature · 1 line
2.43.0
#14 lore raw

RFC PATCH 11/13 crypto: riscv - add vector crypto accelerated SHA-{512,384}

In reply to Eric Biggers

From: Jerry Shih <[email protected]>

Add an implementation of SHA-384 and SHA-512 using the Zvknhb extension. The assembly code is derived from OpenSSL code (openssl/openssl#21923) that was dual-licensed so that it could be reused in the kernel. Nevertheless, the assembly has been significantly reworked for integration with the kernel, for example by using a regular .S file instead of the so-called perlasm, using the assembler instead of bare '.inst', and greatly reducing code duplication.

---
 arch/riscv/crypto/Kconfig                     |  11 +
 arch/riscv/crypto/Makefile                    |   3 +
 arch/riscv/crypto/sha512-riscv64-glue.c       | 133 ++++++++++++
 .../riscv/crypto/sha512-riscv64-zvknhb-zvkb.S | 203 ++++++++++++++++++
 4 files changed, 350 insertions(+)
 create mode 100644 arch/riscv/crypto/sha512-riscv64-glue.c
 create mode 100644 arch/riscv/crypto/sha512-riscv64-zvknhb-zvkb.S
arch/riscv/crypto/Kconfig +11 -0
index 533bc6def123a..ca13895c3e0f6 100644
@@ -58,11 +58,22 @@ config CRYPTO_SHA256_RISCV64
 	tristate "Hash functions: SHA-224 and SHA-256"
 	depends on 64BIT && RISCV_ISA_V && TOOLCHAIN_HAS_VECTOR_CRYPTO
 	select CRYPTO_SHA256
 	help
 	  SHA-224 and SHA-256 secure hash algorithm (FIPS 180)
 
 	  Architecture: riscv64 using:
 	  - Zvknha or Zvknhb vector crypto extensions
 	  - Zvkb vector crypto extension
 
+config CRYPTO_SHA512_RISCV64
+	tristate "Hash functions: SHA-384 and SHA-512"
+	depends on 64BIT && RISCV_ISA_V && TOOLCHAIN_HAS_VECTOR_CRYPTO
+	select CRYPTO_SHA512
+	help
+	  SHA-384 and SHA-512 secure hash algorithm (FIPS 180)
+
+	  Architecture: riscv64 using:
+	  - Zvknhb vector crypto extension
+	  - Zvkb vector crypto extension
+
 endmenu
arch/riscv/crypto/Makefile +3 -0
index 28a58e89927ae..e30a1bcc788bf 100644
@@ -10,10 +10,13 @@ obj-$(CONFIG_CRYPTO_AES_BLOCK_RISCV64) += aes-block-riscv64.o
 aes-block-riscv64-y := aes-riscv64-block-mode-glue.o aes-riscv64-zvkned-zvbb-zvkg.o aes-riscv64-zvkned-zvkb.o
 
 obj-$(CONFIG_CRYPTO_CHACHA_RISCV64) += chacha-riscv64.o
 chacha-riscv64-y := chacha-riscv64-glue.o chacha-riscv64-zvkb.o
 
 obj-$(CONFIG_CRYPTO_GHASH_RISCV64) += ghash-riscv64.o
 ghash-riscv64-y := ghash-riscv64-glue.o ghash-riscv64-zvkg.o
 
 obj-$(CONFIG_CRYPTO_SHA256_RISCV64) += sha256-riscv64.o
 sha256-riscv64-y := sha256-riscv64-glue.o sha256-riscv64-zvknha_or_zvknhb-zvkb.o
+
+obj-$(CONFIG_CRYPTO_SHA512_RISCV64) += sha512-riscv64.o
+sha512-riscv64-y := sha512-riscv64-glue.o sha512-riscv64-zvknhb-zvkb.o
arch/riscv/crypto/sha512-riscv64-glue.c new file +133 -0

133 lines not on this page · raw message

arch/riscv/crypto/sha512-riscv64-zvknhb-zvkb.S new file +203 -0

203 lines not on this page · raw message

Signature · 1 line
2.43.0
#15 lore raw

RFC PATCH 12/13 crypto: riscv - add vector crypto accelerated SM3

In reply to Eric Biggers

From: Jerry Shih <[email protected]>

Add an implementation of SM3 using the Zvksh extension. The assembly code is derived from OpenSSL code (openssl/openssl#21923) that was dual-licensed so that it could be reused in the kernel. Nevertheless, the assembly has been significantly reworked for integration with the kernel, for example by using a regular .S file instead of the so-called perlasm, using the assembler instead of bare '.inst', and greatly reducing code duplication.

---
 arch/riscv/crypto/Kconfig                  |  12 ++
 arch/riscv/crypto/Makefile                 |   3 +
 arch/riscv/crypto/sm3-riscv64-glue.c       | 112 +++++++++++++++++++
 arch/riscv/crypto/sm3-riscv64-zvksh-zvkb.S | 123 +++++++++++++++++++++
 4 files changed, 250 insertions(+)
 create mode 100644 arch/riscv/crypto/sm3-riscv64-glue.c
 create mode 100644 arch/riscv/crypto/sm3-riscv64-zvksh-zvkb.S
arch/riscv/crypto/Kconfig +12 -0
index ca13895c3e0f6..d44911853fa2d 100644
@@ -69,11 +69,23 @@ config CRYPTO_SHA512_RISCV64
 	tristate "Hash functions: SHA-384 and SHA-512"
 	depends on 64BIT && RISCV_ISA_V && TOOLCHAIN_HAS_VECTOR_CRYPTO
 	select CRYPTO_SHA512
 	help
 	  SHA-384 and SHA-512 secure hash algorithm (FIPS 180)
 
 	  Architecture: riscv64 using:
 	  - Zvknhb vector crypto extension
 	  - Zvkb vector crypto extension
 
+config CRYPTO_SM3_RISCV64
+	tristate "Hash functions: SM3 (ShangMi 3)"
+	depends on 64BIT && RISCV_ISA_V && TOOLCHAIN_HAS_VECTOR_CRYPTO
+	select CRYPTO_HASH
+	select CRYPTO_SM3
+	help
+	  SM3 (ShangMi 3) secure hash function (OSCCA GM/T 0004-2012)
+
+	  Architecture: riscv64 using:
+	  - Zvksh vector crypto extension
+	  - Zvkb vector crypto extension
+
 endmenu
arch/riscv/crypto/Makefile +3 -0
index e30a1bcc788bf..4b5efabd1162a 100644
@@ -13,10 +13,13 @@ obj-$(CONFIG_CRYPTO_CHACHA_RISCV64) += chacha-riscv64.o
 chacha-riscv64-y := chacha-riscv64-glue.o chacha-riscv64-zvkb.o
 
 obj-$(CONFIG_CRYPTO_GHASH_RISCV64) += ghash-riscv64.o
 ghash-riscv64-y := ghash-riscv64-glue.o ghash-riscv64-zvkg.o
 
 obj-$(CONFIG_CRYPTO_SHA256_RISCV64) += sha256-riscv64.o
 sha256-riscv64-y := sha256-riscv64-glue.o sha256-riscv64-zvknha_or_zvknhb-zvkb.o
 
 obj-$(CONFIG_CRYPTO_SHA512_RISCV64) += sha512-riscv64.o
 sha512-riscv64-y := sha512-riscv64-glue.o sha512-riscv64-zvknhb-zvkb.o
+
+obj-$(CONFIG_CRYPTO_SM3_RISCV64) += sm3-riscv64.o
+sm3-riscv64-y := sm3-riscv64-glue.o sm3-riscv64-zvksh-zvkb.o
arch/riscv/crypto/sm3-riscv64-glue.c new file +112 -0

112 lines not on this page · raw message

arch/riscv/crypto/sm3-riscv64-zvksh-zvkb.S new file +123 -0

123 lines not on this page · raw message

Signature · 1 line
2.43.0
#16 lore raw

RFC PATCH 13/13 crypto: riscv - add vector crypto accelerated SM4

In reply to Eric Biggers

From: Jerry Shih <[email protected]>

Add an implementation of SM4 using the Zvksed extension. The assembly code is derived from OpenSSL code (openssl/openssl#21923) that was dual-licensed so that it could be reused in the kernel. Nevertheless, the assembly has been significantly reworked for integration with the kernel, for example by using a regular .S file instead of the so-called perlasm, using the assembler instead of bare '.inst', and greatly reducing code duplication.

---
 arch/riscv/crypto/Kconfig                   |  17 +++
 arch/riscv/crypto/Makefile                  |   3 +
 arch/riscv/crypto/sm4-riscv64-glue.c        | 109 ++++++++++++++++++
 arch/riscv/crypto/sm4-riscv64-zvksed-zvkb.S | 117 ++++++++++++++++++++
 4 files changed, 246 insertions(+)
 create mode 100644 arch/riscv/crypto/sm4-riscv64-glue.c
 create mode 100644 arch/riscv/crypto/sm4-riscv64-zvksed-zvkb.S
arch/riscv/crypto/Kconfig +17 -0
index d44911853fa2d..9ba225d968289 100644
@@ -81,11 +81,28 @@ config CRYPTO_SM3_RISCV64
 	depends on 64BIT && RISCV_ISA_V && TOOLCHAIN_HAS_VECTOR_CRYPTO
 	select CRYPTO_HASH
 	select CRYPTO_SM3
 	help
 	  SM3 (ShangMi 3) secure hash function (OSCCA GM/T 0004-2012)
 
 	  Architecture: riscv64 using:
 	  - Zvksh vector crypto extension
 	  - Zvkb vector crypto extension
 
+config CRYPTO_SM4_RISCV64
+	tristate "Ciphers: SM4 (ShangMi 4)"
+	depends on 64BIT && RISCV_ISA_V && TOOLCHAIN_HAS_VECTOR_CRYPTO
+	select CRYPTO_ALGAPI
+	select CRYPTO_SM4
+	help
+	  SM4 block cipher algorithm (OSCCA GB/T 32907-2016,
+	  ISO/IEC 18033-3:2010/Amd 1:2021)
+
+	  SM4 (GBT.32907-2016) is a cryptographic standard issued by the
+	  Organization of State Commercial Administration of China (OSCCA)
+	  as an authorized cryptographic algorithm for use within China.
+
+	  Architecture: riscv64 using:
+	  - Zvksed vector crypto extension
+	  - Zvkb vector crypto extension
+
 endmenu
arch/riscv/crypto/Makefile +3 -0
index 4b5efabd1162a..70d60060d9b26 100644
@@ -16,10 +16,13 @@ obj-$(CONFIG_CRYPTO_GHASH_RISCV64) += ghash-riscv64.o
 ghash-riscv64-y := ghash-riscv64-glue.o ghash-riscv64-zvkg.o
 
 obj-$(CONFIG_CRYPTO_SHA256_RISCV64) += sha256-riscv64.o
 sha256-riscv64-y := sha256-riscv64-glue.o sha256-riscv64-zvknha_or_zvknhb-zvkb.o
 
 obj-$(CONFIG_CRYPTO_SHA512_RISCV64) += sha512-riscv64.o
 sha512-riscv64-y := sha512-riscv64-glue.o sha512-riscv64-zvknhb-zvkb.o
 
 obj-$(CONFIG_CRYPTO_SM3_RISCV64) += sm3-riscv64.o
 sm3-riscv64-y := sm3-riscv64-glue.o sm3-riscv64-zvksh-zvkb.o
+
+obj-$(CONFIG_CRYPTO_SM4_RISCV64) += sm4-riscv64.o
+sm4-riscv64-y := sm4-riscv64-glue.o sm4-riscv64-zvksed-zvkb.o
arch/riscv/crypto/sm4-riscv64-glue.c new file +109 -0

109 lines not on this page · raw message

arch/riscv/crypto/sm4-riscv64-zvksed-zvkb.S new file +117 -0

117 lines not on this page · raw message

Signature · 1 line
2.43.0
#17 lore raw
In reply to Eric Biggers
Quoted 27 lines · Eric Biggers

As discussed previously, the proposed use of the so-called perlasm for the RISC-V crypto assembly files makes them difficult to read, and these files have some other issues such extensively duplicating source code for the different AES key lengths and for the unrolled hash functions. There is/was a desire to share code with OpenSSL, but many of the files have already diverged significantly; also, for most of the algorithms the source code can be quite short anyway, due to the native support for them in the RISC-V vector crypto extensions combined with the way the RISC-V vector extension naturally scales to arbitrary vector lengths.

Since we're still waiting for prerequisite patches to be merged anyway, we have a bit more time to get this cleaned up properly. So I've had a go at cleaning up the patchset to use standard .S files, with the code duplication fixed. I also made some tweaks to make the different algorithms consistent with each other and with what exists in the kernel already for other architectures, and tried to improve comments.

The result is this series, which passes all tests and is about 2400 lines shorter than the latest version with the perlasm
(https://lore.kernel.org/linux-crypto/[email protected]/).
All the same functionality and general optimizations are still included, except for some minor optimizations in XTS that I dropped since it's not clear they are worth the complexity. (Note that almost all users of XTS in the kernel only use it with block-aligned messages, so it's not very important to optimize the ciphertext stealing case.)

Quoted 4 lines

I'd appreciate people's thoughts on this series. Jerry, I hope I'm not stepping on your toes too much here, but I think there are some big improvements here.

As I have indicated before, I fully agree with Eric here that avoiding perlasm is preferable: sharing code with OpenSSL is great if we can simply adopt the exact same code (and track OpenSSL as its upstream) but this never really worked that well for skciphers, due to API differences. (The SHA transforms can be reused a bit more easily)

I will also note that perlasm is not as useful for RISC-V as it is for other architectures: in OpenSSL, perlasm is also used to abstract differences in calling conventions between, e.g., x86_64 on Linux vs Windows, or to support building with outdated [proprietary] toolchains.

I do wonder if we could also use .req directives for register aliases instead of CPP defines? It shouldn't matter for working code, but the diagnostics tend to be a bit more useful if the aliases are visible to the assembler.

Quoted 88 lines

This series is based on riscv/for-next
(https://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux.git/log/?h=for-next)
commit f352a28cc2fb4ee8d08c6a6362c9a861fcc84236, and for convenience I've included the prerequisite patches too.

Andy Chiu (1):
riscv: vector: make Vector always available for softirq context

Eric Biggers (1):
RISC-V: add TOOLCHAIN_HAS_VECTOR_CRYPTO

Greentime Hu (1):
riscv: Add support for kernel mode vector

Heiko Stuebner (2):
RISC-V: add helper function to read the vector VLEN
RISC-V: hook new crypto subdir into build-system

Jerry Shih (8):
crypto: riscv - add vector crypto accelerated AES
crypto: riscv - add vector crypto accelerated AES-{ECB,CBC,CTR,XTS}
crypto: riscv - add vector crypto accelerated ChaCha20
crypto: riscv - add vector crypto accelerated GHASH
crypto: riscv - add vector crypto accelerated SHA-{256,224}
crypto: riscv - add vector crypto accelerated SHA-{512,384}
crypto: riscv - add vector crypto accelerated SM3
crypto: riscv - add vector crypto accelerated SM4

 arch/riscv/Kbuild                             |   1 +
 arch/riscv/Kconfig                            |   7 +
 arch/riscv/crypto/Kconfig                     | 108 +++++
 arch/riscv/crypto/Makefile                    |  28 ++
 arch/riscv/crypto/aes-macros.S                | 156 +++++++
 .../crypto/aes-riscv64-block-mode-glue.c      | 435 ++++++++++++++++++
 arch/riscv/crypto/aes-riscv64-glue.c          | 123 +++++
 arch/riscv/crypto/aes-riscv64-glue.h          |  15 +
 .../crypto/aes-riscv64-zvkned-zvbb-zvkg.S     | 300 ++++++++++++
 arch/riscv/crypto/aes-riscv64-zvkned-zvkb.S   | 146 ++++++
 arch/riscv/crypto/aes-riscv64-zvkned.S        | 180 ++++++++
 arch/riscv/crypto/chacha-riscv64-glue.c       | 101 ++++
 arch/riscv/crypto/chacha-riscv64-zvkb.S       | 294 ++++++++++++
 arch/riscv/crypto/ghash-riscv64-glue.c        | 170 +++++++
 arch/riscv/crypto/ghash-riscv64-zvkg.S        |  72 +++
 arch/riscv/crypto/sha256-riscv64-glue.c       | 137 ++++++
 .../sha256-riscv64-zvknha_or_zvknhb-zvkb.S    | 225 +++++++++
 arch/riscv/crypto/sha512-riscv64-glue.c       | 133 ++++++
 .../riscv/crypto/sha512-riscv64-zvknhb-zvkb.S | 203 ++++++++
 arch/riscv/crypto/sm3-riscv64-glue.c          | 112 +++++
 arch/riscv/crypto/sm3-riscv64-zvksh-zvkb.S    | 123 +++++
 arch/riscv/crypto/sm4-riscv64-glue.c          | 109 +++++
 arch/riscv/crypto/sm4-riscv64-zvksed-zvkb.S   | 117 +++++
 arch/riscv/include/asm/processor.h            |  14 +-
 arch/riscv/include/asm/simd.h                 |  48 ++
 arch/riscv/include/asm/vector.h               |  20 +
 arch/riscv/kernel/Makefile                    |   1 +
 arch/riscv/kernel/kernel_mode_vector.c        | 126 +++++
 arch/riscv/kernel/process.c                   |   1 +
 crypto/Kconfig                                |   3 +
 30 files changed, 3507 insertions(+), 1 deletion(-)
 create mode 100644 arch/riscv/crypto/Kconfig
 create mode 100644 arch/riscv/crypto/Makefile
 create mode 100644 arch/riscv/crypto/aes-macros.S
 create mode 100644 arch/riscv/crypto/aes-riscv64-block-mode-glue.c
 create mode 100644 arch/riscv/crypto/aes-riscv64-glue.c
 create mode 100644 arch/riscv/crypto/aes-riscv64-glue.h
 create mode 100644 arch/riscv/crypto/aes-riscv64-zvkned-zvbb-zvkg.S
 create mode 100644 arch/riscv/crypto/aes-riscv64-zvkned-zvkb.S
 create mode 100644 arch/riscv/crypto/aes-riscv64-zvkned.S
 create mode 100644 arch/riscv/crypto/chacha-riscv64-glue.c
 create mode 100644 arch/riscv/crypto/chacha-riscv64-zvkb.S
 create mode 100644 arch/riscv/crypto/ghash-riscv64-glue.c
 create mode 100644 arch/riscv/crypto/ghash-riscv64-zvkg.S
 create mode 100644 arch/riscv/crypto/sha256-riscv64-glue.c
 create mode 100644 arch/riscv/crypto/sha256-riscv64-zvknha_or_zvknhb-zvkb.S
 create mode 100644 arch/riscv/crypto/sha512-riscv64-glue.c
 create mode 100644 arch/riscv/crypto/sha512-riscv64-zvknhb-zvkb.S
 create mode 100644 arch/riscv/crypto/sm3-riscv64-glue.c
 create mode 100644 arch/riscv/crypto/sm3-riscv64-zvksh-zvkb.S
 create mode 100644 arch/riscv/crypto/sm4-riscv64-glue.c
 create mode 100644 arch/riscv/crypto/sm4-riscv64-zvksed-zvkb.S
 create mode 100644 arch/riscv/include/asm/simd.h
 create mode 100644 arch/riscv/kernel/kernel_mode_vector.c

base-commit: f352a28cc2fb4ee8d08c6a6362c9a861fcc84236 --
2.43.0

#18 lore raw
Quoted 45 lines · Ard Biesheuvel
Quoted 27 lines · Eric Biggers

As discussed previously, the proposed use of the so-called perlasm for the RISC-V crypto assembly files makes them difficult to read, and these files have some other issues such extensively duplicating source code for the different AES key lengths and for the unrolled hash functions. There is/was a desire to share code with OpenSSL, but many of the files have already diverged significantly; also, for most of the algorithms the source code can be quite short anyway, due to the native support for them in the RISC-V vector crypto extensions combined with the way the RISC-V vector extension naturally scales to arbitrary vector lengths.

Since we're still waiting for prerequisite patches to be merged anyway, we have a bit more time to get this cleaned up properly. So I've had a go at cleaning up the patchset to use standard .S files, with the code duplication fixed. I also made some tweaks to make the different algorithms consistent with each other and with what exists in the kernel already for other architectures, and tried to improve comments.

The result is this series, which passes all tests and is about 2400 lines shorter than the latest version with the perlasm
(https://lore.kernel.org/linux-crypto/[email protected]/).
All the same functionality and general optimizations are still included, except for some minor optimizations in XTS that I dropped since it's not clear they are worth the complexity. (Note that almost all users of XTS in the kernel only use it with block-aligned messages, so it's not very important to optimize the ciphertext stealing case.)

Quoted 4 lines

I'd appreciate people's thoughts on this series. Jerry, I hope I'm not stepping on your toes too much here, but I think there are some big improvements here.

As I have indicated before, I fully agree with Eric here that avoiding perlasm is preferable: sharing code with OpenSSL is great if we can simply adopt the exact same code (and track OpenSSL as its upstream) but this never really worked that well for skciphers, due to API differences. (The SHA transforms can be reused a bit more easily)

I will also note that perlasm is not as useful for RISC-V as it is for other architectures: in OpenSSL, perlasm is also used to abstract differences in calling conventions between, e.g., x86_64 on Linux vs Windows, or to support building with outdated [proprietary] toolchains.

Quoted 4 lines

I do wonder if we could also use .req directives for register aliases instead of CPP defines? It shouldn't matter for working code, but the diagnostics tend to be a bit more useful if the aliases are visible to the assembler.

.req unfortunately isn't an option since it is specific to AArch64 and ARM assembly. So we have to use #defines like x86 does. Ultimately, the effect is about the same.

- Eric

#19 lore raw
Quoted 13 lines · Eric Biggers
Quoted 12 lines · Ard Biesheuvel
Quoted 11 lines · Eric Biggers

As discussed previously, the proposed use of the so-called perlasm for the RISC-V crypto assembly files makes them difficult to read, and these files have some other issues such extensively duplicating source code for the different AES key lengths and for the unrolled hash functions. There is/was a desire to share code with OpenSSL, but many of the files have already diverged significantly; also, for most of the algorithms the source code can be quite short anyway, due to the native support for them in the RISC-V vector crypto extensions combined with the way the RISC-V vector extension naturally scales to arbitrary vector lengths.

Quoted 5 lines
Quoted 5 lines
Quoted 5 lines

Since we're still waiting for prerequisite patches to be merged anyway, we have a bit more time to get this cleaned up properly. So I've had a go at cleaning up the patchset to use standard .S files, with the code duplication fixed. I also made some tweaks to make the different algorithms consistent with each other and with what exists in the kernel

Do you mean the xts gluing part only? Do we have the different algorithms for the actual implementation in .S?

Quoted 1 line
Quoted 1 line
Quoted 1 line

already for other architectures, and tried to improve comments.

The improved comments are better. Thanks.

Quoted 3 lines
Quoted 3 lines
Quoted 3 lines

The result is this series, which passes all tests and is about 2400 lines shorter than the latest version with the perlasm
(https://lore.kernel.org/linux-crypto/[email protected]/).

For the unrolled hash functions case(sha256/512), the .S implementation uses macro instead. But I think the macro expanded code will be the same. Do we care about the source code size instead of the final binary code size?

For the AES variants part, the .S uses branches inside the inner loop. Does the branch inside the inner loop better than the bigger code size?

Quoted 5 lines
Quoted 5 lines
Quoted 5 lines

All the same functionality and general optimizations are still included, except for some minor optimizations in XTS that I dropped since it's not clear they are worth the complexity. (Note that almost all users of XTS in the kernel only use it with block-aligned messages, so it's not very important to optimize the ciphertext stealing case.)

The aesni/neon are SIMD, so I think the rvv version could have the different design. And I think my implementation is very similar to x86-xts except the tail block numbers for ciphertext stealing case.
The x86-xts-like implementation uses the fixed 2 block for the ciphertext stealing case.

+ int xts_blocks = DIV_ROUND_UP(req->cryptlen,
+ AES_BLOCK_SIZE) - 2;

Quoted 10 lines
Quoted 10 lines
Quoted 4 lines

I'd appreciate people's thoughts on this series. Jerry, I hope I'm not stepping on your toes too much here, but I think there are some big improvements here.

As I have indicated before, I fully agree with Eric here that avoiding perlasm is preferable: sharing code with OpenSSL is great if we can simply adopt the exact same code (and track OpenSSL as its upstream) but this never really worked that well for skciphers, due to API differences. (The SHA transforms can be reused a bit more easily)

In my opinion, I would prefer the perlasm with the usage of asm mnemonics. I could see the expanded asm source from perlsm. I don't know how to dump the expanded asm source when we use asm .macro directives. I use objdump to see the final asm.
And we could use function to modularize the asm implementations. The macro might do the same things, but it's more clear for me for the argument passing and more powerful string manipulation.
And I could have scope for the register name binding. It's more clear to me comparing with a long list of #define xxx.

If the pure .S is still more preferable in kernel, let's do that.

-Jerry

Quoted 16 lines
Quoted 10 lines

I will also note that perlasm is not as useful for RISC-V as it is for other architectures: in OpenSSL, perlasm is also used to abstract differences in calling conventions between, e.g., x86_64 on Linux vs Windows, or to support building with outdated [proprietary] toolchains.

I do wonder if we could also use .req directives for register aliases instead of CPP defines? It shouldn't matter for working code, but the diagnostics tend to be a bit more useful if the aliases are visible to the assembler.

.req unfortunately isn't an option since it is specific to AArch64 and ARM assembly. So we have to use #defines like x86 does. Ultimately, the effect is about the same.

- Eric

#20 lore raw
Quoted 14 lines · Jerry Shih
Quoted 13 lines · Eric Biggers
Quoted 12 lines · Ard Biesheuvel
Quoted 11 lines · Eric Biggers

As discussed previously, the proposed use of the so-called perlasm for the RISC-V crypto assembly files makes them difficult to read, and these files have some other issues such extensively duplicating source code for the different AES key lengths and for the unrolled hash functions. There is/was a desire to share code with OpenSSL, but many of the files have already diverged significantly; also, for most of the algorithms the source code can be quite short anyway, due to the native support for them in the RISC-V vector crypto extensions combined with the way the RISC-V vector extension naturally scales to arbitrary vector lengths.

Quoted 8 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines

Since we're still waiting for prerequisite patches to be merged anyway, we have a bit more time to get this cleaned up properly. So I've had a go at cleaning up the patchset to use standard .S files, with the code duplication fixed. I also made some tweaks to make the different algorithms consistent with each other and with what exists in the kernel

Do you mean the xts gluing part only? Do we have the different algorithms for the actual implementation in .S?

I did change both the XTS assembly and XTS glue code slightly. However, the general approach is still the same, except for a couple minor optimizations that I dropped. See what I wrote below:

All the same functionality and general optimizations are still included, except for some minor optimizations in XTS that I dropped since it's not clear they are worth the complexity. (Note that almost all users of XTS in the kernel only use it with block-aligned messages, so it's not very important to optimize the ciphertext stealing case.)

Quoted 7 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines

The result is this series, which passes all tests and is about 2400 lines shorter than the latest version with the perlasm
(https://lore.kernel.org/linux-crypto/[email protected]/).

For the unrolled hash functions case(sha256/512), the .S implementation uses macro instead. But I think the macro expanded code will be the same. Do we care about the source code size instead of the final binary code size?

Yes, because it's very difficult to review code that's been hand-unrolled. Essentially what I had been doing to review your code was to reverse engineer what the loop that was being unrolled was, and then go through each unrolled iteration and verify that it matches what it is supposed to. (While also ignoring the code comments, as some of the comments had been copy+pasted without being updated to be correct for what iteration they were commenting.)

It's much simpler to just use .rept to unroll the code for us.

Quoted 1 line

For the AES variants part, the .S uses branches inside the inner loop.

No, it does not. The macros generate a separate inner loop for each AES key length, just like what the perl scripts had. The source code just isn't duplicated 3 times anymore.

Quoted 13 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines

All the same functionality and general optimizations are still included, except for some minor optimizations in XTS that I dropped since it's not clear they are worth the complexity. (Note that almost all users of XTS in the kernel only use it with block-aligned messages, so it's not very important to optimize the ciphertext stealing case.)

The aesni/neon are SIMD, so I think the rvv version could have the different design. And I think my implementation is very similar to x86-xts except the tail block numbers for ciphertext stealing case.
The x86-xts-like implementation uses the fixed 2 block for the ciphertext stealing case.

Review

Quoted 2 lines
(quoted diff) +2 -0
+		int xts_blocks = DIV_ROUND_UP(req->cryptlen,
+					      AES_BLOCK_SIZE) - 2;

The two specific XTS optimizations that I dropped are:

1. There was a parameter 'update_iv' that told the assembly code whether to calculate and return the next tweak or not. Computing the next tweak is a fairly small computation; it's not clear to me that it's worth adding a branch and extra code complexity to skip that computation.

2. For XTS encryption with ciphertext stealing, the assembly code encrypted the last full block during the main loop instead of separately, in order to take better advantage of parallelism. I don't like how this optimization only applied to inputs whose length is not a multiple of 16, which are very rare. Also, it only applied to encryption, not to decryption. That meant that separate code was needed for encryption and decryption. Note that for disk encryption, decryption is more performance-critical than encryption.

Again, we could bring these back later. I'd just like to error on the side of simplicity for the initial version. If we include optimizations that aren't actually worthwhile, it might be hard to remove them later.

Quoted 11 lines
Quoted 10 lines
Quoted 10 lines
Quoted 4 lines

I'd appreciate people's thoughts on this series. Jerry, I hope I'm not stepping on your toes too much here, but I think there are some big improvements here.

As I have indicated before, I fully agree with Eric here that avoiding perlasm is preferable: sharing code with OpenSSL is great if we can simply adopt the exact same code (and track OpenSSL as its upstream) but this never really worked that well for skciphers, due to API differences. (The SHA transforms can be reused a bit more easily)

Quoted 4 lines

In my opinion, I would prefer the perlasm with the usage of asm mnemonics. I could see the expanded asm source from perlsm. I don't know how to dump the expanded asm source when we use asm .macro directives. I use objdump to see the final asm.

Yes, you can always use objdump to see everything expanded out. But there's not much of a need to do that when you can just read the source code instead.

Quoted 3 lines

And we could use function to modularize the asm implementations. The macro might do the same things, but it's more clear for me for the argument passing and more powerful string manipulation.

The perl scripts were not using any advanced capabilities of perl, and in some cases they even emitted assembly macros like .rept instead of using perl. So the use of perl seemed unnecessary and just over-complicated things.

BTW, we could always use perlasm for specific algorithms where we actually need advanced scripting, like to interleave two independent computations with each other. It doesn't have to be all one or the other. It's just that the code that's been written for RISC-V so far is relatively straightforward and doesn't seem to benefit from perlasm.

Quoted 2 lines

And I could have scope for the register name binding. It's more clear to me comparing with a long list of #define xxx.

I think it's good enough. We can always re-#define things later in the file, or just split functions with different parameters into different files.

BTW, the reason that some of the lists of defines got longer is that I actually gave things proper names, whereas some the perl scripts used trivial names like "V28" for the v28 register.

- Eric