Commit 4f307857f9 for openssl.org
commit 4f307857f9bde35039517e55468e929560a716ff
Author: Julian Zhu <julian.oerv@isrc.iscas.ac.cn>
Date: Mon Sep 7 12:33:25 2026 +0800
RISC-V: handle misaligned input in the SHA-512 core
Build each doubleword from two aligned loads when the input is misaligned,
as for SHA-256, instead of relying on slow misaligned ld.
Signed-off-by: Julian Zhu <julian.oerv@isrc.iscas.ac.cn>
Reviewed-by: Paul Dale <paul.dale@oracle.com>
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
Merge-date: Fri Oct 2 08:26:49 2026
Merged-from: https://github.com/openssl/openssl/pull/33008
diff --git a/crypto/sha/asm/sha512-riscv64-zbb.pl b/crypto/sha/asm/sha512-riscv64-zbb.pl
index 142c32b3a6..7edae831d9 100644
--- a/crypto/sha/asm/sha512-riscv64-zbb.pl
+++ b/crypto/sha/asm/sha512-riscv64-zbb.pl
@@ -62,15 +62,34 @@ my $K512 = "K512";
# Function arguments
my ($INP, $LEN, $ADDR) = ("a1", "a2", "sp");
my ($KT, $T1, $T2, $T3, $T4, $T5, $T6) = ("t0", "t1", "t2", "t3", "t4", "t5", "t6");
+# Shift amounts for misaligned input
+my ($SHL, $SHR) = ("a3", "a4");
+my ($MISALIGNED_INPUT, $ALIGNED_INPUT) = (0, 1);
# Parity-indexed pairs: W = W[i], U = W[i-15], X = a ^ b
my ($W0, $W1, $U0, $U1, $X0, $X1) = ("a5", "a6", "a7", "s0", "s1", "s10");
my ($A, $B, $C, $D ,$E ,$F ,$G ,$H) = ("s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9");
+# Misaligned: $dst = (lo >> SHL) | (hi << SHR) from two aligned loads
+sub loadDword {
+ my ($ALIGNED, $dst, $off) = @_;
+ if ($ALIGNED) {
+ return "ld $dst, $off($INP)";
+ }
+ my $code=<<___;
+ ld $T5, $off($INP)
+ ld $T6, ($off+8)($INP)
+ srl $dst, $T5, $SHL
+ sll $T6, $T6, $SHR
+ or $dst, $dst, $T6
+___
+ return $code;
+}
+
sub MSGSCHEDULE0 {
- my ($index) = @_;
+ my ($ALIGNED, $index) = @_;
my $Wi = ($index & 1) ? $W1 : $W0;
my $code=<<___;
- ld $Wi, 8*$index($INP)
+ @{[loadDword $ALIGNED, $Wi, "8*$index"]}
@{[rev8 $Wi, $Wi]}
sd $Wi, 8*$index($ADDR)
___
@@ -165,9 +184,9 @@ ___
}
sub SHA512ROUND0 {
- my ($INDEX, $a, $b, $c, $d, $e, $f, $g, $h) = @_;
+ my ($ALIGNED, $INDEX, $a, $b, $c, $d, $e, $f, $g, $h) = @_;
my $code=<<___;
- @{[MSGSCHEDULE0 $INDEX]}
+ @{[MSGSCHEDULE0 $ALIGNED, $INDEX]}
@{[SHA512ROUND $INDEX, $a, $b, $c, $d, $e, $f, $g, $h]}
___
@@ -184,6 +203,7 @@ ___
return $code;
}
+
################################################################################
# void sha512_block_data_order_zbb(void *c, const void *p, size_t len)
$code .= <<___;
@@ -221,28 +241,57 @@ sha512_block_data_order_zbb:
ld $G, 48(a0)
ld $H, 56(a0)
+ andi $SHL, $INP, 7
+ beqz $SHL, L_round_loop
+ andi $INP, $INP, -8
+ slli $SHL, $SHL, 3
+ li $T1, 64
+ sub $SHR, $T1, $SHL
+
L_round_loop:
# Decrement length by 1
addi $LEN, $LEN, -1
# b ^ c for round 0's Maj; later rounds reuse the previous a ^ b
xor $X1, $B, $C
+
+ bnez $SHL, L_load_misaligned
+___
+
+# Rounds 0..15, once for aligned and once for misaligned input
+for (my $i = 0; $i < 16; $i += 8) {
+ $code .= <<___;
+ @{[SHA512ROUND0 $ALIGNED_INPUT, $i, $A, $B, $C, $D, $E, $F, $G, $H]}
+ @{[SHA512ROUND0 $ALIGNED_INPUT, $i+1, $H, $A, $B, $C, $D, $E, $F, $G]}
+ @{[SHA512ROUND0 $ALIGNED_INPUT, $i+2, $G, $H, $A, $B, $C, $D, $E, $F]}
+ @{[SHA512ROUND0 $ALIGNED_INPUT, $i+3, $F, $G, $H, $A, $B, $C, $D, $E]}
+ @{[SHA512ROUND0 $ALIGNED_INPUT, $i+4, $E, $F, $G, $H, $A, $B, $C, $D]}
+ @{[SHA512ROUND0 $ALIGNED_INPUT, $i+5, $D, $E, $F, $G, $H, $A, $B, $C]}
+ @{[SHA512ROUND0 $ALIGNED_INPUT, $i+6, $C, $D, $E, $F, $G, $H, $A, $B]}
+ @{[SHA512ROUND0 $ALIGNED_INPUT, $i+7, $B, $C, $D, $E, $F, $G, $H, $A]}
+___
+}
+
+$code .= <<___;
+ j L_message_schedule
+L_load_misaligned:
___
for (my $i = 0; $i < 16; $i += 8) {
$code .= <<___;
- @{[SHA512ROUND0 $i, $A, $B, $C, $D, $E, $F, $G, $H]}
- @{[SHA512ROUND0 $i+1, $H, $A, $B, $C, $D, $E, $F, $G]}
- @{[SHA512ROUND0 $i+2, $G, $H, $A, $B, $C, $D, $E, $F]}
- @{[SHA512ROUND0 $i+3, $F, $G, $H, $A, $B, $C, $D, $E]}
- @{[SHA512ROUND0 $i+4, $E, $F, $G, $H, $A, $B, $C, $D]}
- @{[SHA512ROUND0 $i+5, $D, $E, $F, $G, $H, $A, $B, $C]}
- @{[SHA512ROUND0 $i+6, $C, $D, $E, $F, $G, $H, $A, $B]}
- @{[SHA512ROUND0 $i+7, $B, $C, $D, $E, $F, $G, $H, $A]}
+ @{[SHA512ROUND0 $MISALIGNED_INPUT, $i, $A, $B, $C, $D, $E, $F, $G, $H]}
+ @{[SHA512ROUND0 $MISALIGNED_INPUT, $i+1, $H, $A, $B, $C, $D, $E, $F, $G]}
+ @{[SHA512ROUND0 $MISALIGNED_INPUT, $i+2, $G, $H, $A, $B, $C, $D, $E, $F]}
+ @{[SHA512ROUND0 $MISALIGNED_INPUT, $i+3, $F, $G, $H, $A, $B, $C, $D, $E]}
+ @{[SHA512ROUND0 $MISALIGNED_INPUT, $i+4, $E, $F, $G, $H, $A, $B, $C, $D]}
+ @{[SHA512ROUND0 $MISALIGNED_INPUT, $i+5, $D, $E, $F, $G, $H, $A, $B, $C]}
+ @{[SHA512ROUND0 $MISALIGNED_INPUT, $i+6, $C, $D, $E, $F, $G, $H, $A, $B]}
+ @{[SHA512ROUND0 $MISALIGNED_INPUT, $i+7, $B, $C, $D, $E, $F, $G, $H, $A]}
___
}
$code .= <<___;
+L_message_schedule:
# Round 16's W[i-16] is W[0]; later rounds reuse the previous W[i-15]
ld $U1, 0($ADDR)
___