chacha/asm/chacha-armv8.pl: preserve FP registers d8 and d9 correctly
authorArd Biesheuvel <ard.biesheuvel@arm.com>
Thu, 21 Nov 2019 17:13:41 +0000 (18:13 +0100)
committerTomas Mraz <tmraz@fedoraproject.org>
Thu, 28 Nov 2019 15:40:43 +0000 (16:40 +0100)
Depending on the size of the input, we may take different paths through
the accelerated arm64 ChaCha20 routines, each of which use a different
subset of the FP registers, some of which need to be preserved and
restored, as required by the AArch64 calling convention (AAPCS64)

In some cases, (e.g., when the input size is 640 bytes), we call the 512
byte NEON path followed directly by the scalar path, and in this case,
we preserve and restore d8 and d9, only to clobber them again
immediately before handing over to the scalar path which does not touch
the FP registers at all, and hence does not restore them either.

Fix this by moving the restoration of d8 and d9 to a later stage in the
512 byte routine, either before calling the scalar path, or when exiting
the function.

Fixes #10470
CLA: trivial

Reviewed-by: Paul Dale <paul.dale@oracle.com>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/10497)

crypto/chacha/asm/chacha-armv8.pl

index aed873d57ef8208f8e75f0eb543a0a065a2d41aa..7868389f7166f23bee710dc57404a6cc8999c6ca 100755 (executable)
@@ -1232,8 +1232,7 @@ $code.=<<___;
        adds    $len,$len,#512
        ushr    $ONE,$ONE,#1                    // 4 -> 2
 
-       ldp     d8,d9,[sp,#128+0]               // meet ABI requirements
-       ldp     d10,d11,[sp,#128+16]
+       ldp     d10,d11,[sp,#128+16]            // meet ABI requirements
        ldp     d12,d13,[sp,#128+32]
        ldp     d14,d15,[sp,#128+48]
 
@@ -1250,6 +1249,7 @@ $code.=<<___;
        ld1     {$CTR,$ROT24},[$key]
        b.hs    .Loop_outer_neon
 
+       ldp     d8,d9,[sp,#0]                   // meet ABI requirements
        eor     @K[1],@K[1],@K[1]
        eor     @K[2],@K[2],@K[2]
        eor     @K[3],@K[3],@K[3]
@@ -1259,6 +1259,7 @@ $code.=<<___;
        b       .Loop_outer
 
 .Ldone_512_neon:
+       ldp     d8,d9,[sp,#128+0]               // meet ABI requirements
        ldp     x19,x20,[x29,#16]
        add     sp,sp,#128+64
        ldp     x21,x22,[x29,#32]