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)
 ___