From 0b633485c0dd916985b595b721cdbedceea4518a Mon Sep 17 00:00:00 2001 From: kaleb-himes Date: Wed, 4 Nov 2026 10:43:43 -0700 Subject: [PATCH 1/3] ppc64 SHA-2 crypto asm: byte-swap message words on little-endian --- wolfcrypt/src/port/ppc64/ppc64-sha256-asm.S | 17 +++++++++++ wolfcrypt/src/port/ppc64/ppc64-sha256-asm_c.c | 17 +++++++++++ wolfcrypt/src/port/ppc64/ppc64-sha512-asm.S | 29 +++++++++++++++++++ wolfcrypt/src/port/ppc64/ppc64-sha512-asm_c.c | 29 +++++++++++++++++++ 4 files changed, 92 insertions(+) diff --git a/wolfcrypt/src/port/ppc64/ppc64-sha256-asm.S b/wolfcrypt/src/port/ppc64/ppc64-sha256-asm.S index 7deabbf0cef..55d0181fb19 100644 --- a/wolfcrypt/src/port/ppc64/ppc64-sha256-asm.S +++ b/wolfcrypt/src/port/ppc64/ppc64-sha256-asm.S @@ -3494,22 +3494,39 @@ L_SHA256_crypto_begin: vsldoi 6, 4, 4, 8 vsldoi 7, 4, 4, 12 # Load message, one word per vector register +#ifdef __LITTLE_ENDIAN__ + lvsl 9, 0, 8 + vspltisb 10, 3 + vxor 9, 9, 10 +#endif /* __LITTLE_ENDIAN__ */ lxvw4x 48, 0, 4 +#ifdef __LITTLE_ENDIAN__ + vperm 16, 16, 16, 9 +#endif /* __LITTLE_ENDIAN__ */ addi 4, 4, 16 vsldoi 17, 16, 16, 4 vsldoi 18, 16, 16, 8 vsldoi 19, 16, 16, 12 lxvw4x 52, 0, 4 +#ifdef __LITTLE_ENDIAN__ + vperm 20, 20, 20, 9 +#endif /* __LITTLE_ENDIAN__ */ addi 4, 4, 16 vsldoi 21, 20, 20, 4 vsldoi 22, 20, 20, 8 vsldoi 23, 20, 20, 12 lxvw4x 56, 0, 4 +#ifdef __LITTLE_ENDIAN__ + vperm 24, 24, 24, 9 +#endif /* __LITTLE_ENDIAN__ */ addi 4, 4, 16 vsldoi 25, 24, 24, 4 vsldoi 26, 24, 24, 8 vsldoi 27, 24, 24, 12 lxvw4x 60, 0, 4 +#ifdef __LITTLE_ENDIAN__ + vperm 28, 28, 28, 9 +#endif /* __LITTLE_ENDIAN__ */ addi 4, 4, 16 vsldoi 29, 28, 28, 4 vsldoi 30, 28, 28, 8 diff --git a/wolfcrypt/src/port/ppc64/ppc64-sha256-asm_c.c b/wolfcrypt/src/port/ppc64/ppc64-sha256-asm_c.c index c7833ca99d1..6b3b087d848 100644 --- a/wolfcrypt/src/port/ppc64/ppc64-sha256-asm_c.c +++ b/wolfcrypt/src/port/ppc64/ppc64-sha256-asm_c.c @@ -3422,22 +3422,39 @@ void Transform_Sha256_Len_crypto(wc_Sha256* sha256, const byte* data, "vsldoi 6, 4, 4, 8\n\t" "vsldoi 7, 4, 4, 12\n\t" /* Load message, one word per vector register */ +#ifdef __LITTLE_ENDIAN__ + "lvsl 9, 0, 8\n\t" + "vspltisb 10, 3\n\t" + "vxor 9, 9, 10\n\t" +#endif /* __LITTLE_ENDIAN__ */ "lxvw4x 48, 0, %[data]\n\t" +#ifdef __LITTLE_ENDIAN__ + "vperm 16, 16, 16, 9\n\t" +#endif /* __LITTLE_ENDIAN__ */ "addi %[data], %[data], 16\n\t" "vsldoi 17, 16, 16, 4\n\t" "vsldoi 18, 16, 16, 8\n\t" "vsldoi 19, 16, 16, 12\n\t" "lxvw4x 52, 0, %[data]\n\t" +#ifdef __LITTLE_ENDIAN__ + "vperm 20, 20, 20, 9\n\t" +#endif /* __LITTLE_ENDIAN__ */ "addi %[data], %[data], 16\n\t" "vsldoi 21, 20, 20, 4\n\t" "vsldoi 22, 20, 20, 8\n\t" "vsldoi 23, 20, 20, 12\n\t" "lxvw4x 56, 0, %[data]\n\t" +#ifdef __LITTLE_ENDIAN__ + "vperm 24, 24, 24, 9\n\t" +#endif /* __LITTLE_ENDIAN__ */ "addi %[data], %[data], 16\n\t" "vsldoi 25, 24, 24, 4\n\t" "vsldoi 26, 24, 24, 8\n\t" "vsldoi 27, 24, 24, 12\n\t" "lxvw4x 60, 0, %[data]\n\t" +#ifdef __LITTLE_ENDIAN__ + "vperm 28, 28, 28, 9\n\t" +#endif /* __LITTLE_ENDIAN__ */ "addi %[data], %[data], 16\n\t" "vsldoi 29, 28, 28, 4\n\t" "vsldoi 30, 28, 28, 8\n\t" diff --git a/wolfcrypt/src/port/ppc64/ppc64-sha512-asm.S b/wolfcrypt/src/port/ppc64/ppc64-sha512-asm.S index 307a0fb1ec0..20837d8b394 100644 --- a/wolfcrypt/src/port/ppc64/ppc64-sha512-asm.S +++ b/wolfcrypt/src/port/ppc64/ppc64-sha512-asm.S @@ -4185,28 +4185,57 @@ L_SHA512_crypto_begin: vsldoi 5, 4, 4, 8 vsldoi 7, 6, 6, 8 # Load message, one doubleword per vector register +#ifdef __LITTLE_ENDIAN__ + lvsl 9, 0, 8 + vspltisb 10, 7 + vxor 9, 9, 10 +#endif /* __LITTLE_ENDIAN__ */ lxvd2x 48, 0, 4 +#ifdef __LITTLE_ENDIAN__ + vperm 16, 16, 16, 9 +#endif /* __LITTLE_ENDIAN__ */ addi 4, 4, 16 vsldoi 17, 16, 16, 8 lxvd2x 50, 0, 4 +#ifdef __LITTLE_ENDIAN__ + vperm 18, 18, 18, 9 +#endif /* __LITTLE_ENDIAN__ */ addi 4, 4, 16 vsldoi 19, 18, 18, 8 lxvd2x 52, 0, 4 +#ifdef __LITTLE_ENDIAN__ + vperm 20, 20, 20, 9 +#endif /* __LITTLE_ENDIAN__ */ addi 4, 4, 16 vsldoi 21, 20, 20, 8 lxvd2x 54, 0, 4 +#ifdef __LITTLE_ENDIAN__ + vperm 22, 22, 22, 9 +#endif /* __LITTLE_ENDIAN__ */ addi 4, 4, 16 vsldoi 23, 22, 22, 8 lxvd2x 56, 0, 4 +#ifdef __LITTLE_ENDIAN__ + vperm 24, 24, 24, 9 +#endif /* __LITTLE_ENDIAN__ */ addi 4, 4, 16 vsldoi 25, 24, 24, 8 lxvd2x 58, 0, 4 +#ifdef __LITTLE_ENDIAN__ + vperm 26, 26, 26, 9 +#endif /* __LITTLE_ENDIAN__ */ addi 4, 4, 16 vsldoi 27, 26, 26, 8 lxvd2x 60, 0, 4 +#ifdef __LITTLE_ENDIAN__ + vperm 28, 28, 28, 9 +#endif /* __LITTLE_ENDIAN__ */ addi 4, 4, 16 vsldoi 29, 28, 28, 8 lxvd2x 62, 0, 4 +#ifdef __LITTLE_ENDIAN__ + vperm 30, 30, 30, 9 +#endif /* __LITTLE_ENDIAN__ */ addi 4, 4, 16 vsldoi 31, 30, 30, 8 # Preload first key diff --git a/wolfcrypt/src/port/ppc64/ppc64-sha512-asm_c.c b/wolfcrypt/src/port/ppc64/ppc64-sha512-asm_c.c index e455ab480dd..80e55ed3f29 100644 --- a/wolfcrypt/src/port/ppc64/ppc64-sha512-asm_c.c +++ b/wolfcrypt/src/port/ppc64/ppc64-sha512-asm_c.c @@ -4113,28 +4113,57 @@ void Transform_Sha512_Len_crypto(wc_Sha512* sha512, const byte* data, "vsldoi 5, 4, 4, 8\n\t" "vsldoi 7, 6, 6, 8\n\t" /* Load message, one doubleword per vector register */ +#ifdef __LITTLE_ENDIAN__ + "lvsl 9, 0, 8\n\t" + "vspltisb 10, 7\n\t" + "vxor 9, 9, 10\n\t" +#endif /* __LITTLE_ENDIAN__ */ "lxvd2x 48, 0, %[data]\n\t" +#ifdef __LITTLE_ENDIAN__ + "vperm 16, 16, 16, 9\n\t" +#endif /* __LITTLE_ENDIAN__ */ "addi %[data], %[data], 16\n\t" "vsldoi 17, 16, 16, 8\n\t" "lxvd2x 50, 0, %[data]\n\t" +#ifdef __LITTLE_ENDIAN__ + "vperm 18, 18, 18, 9\n\t" +#endif /* __LITTLE_ENDIAN__ */ "addi %[data], %[data], 16\n\t" "vsldoi 19, 18, 18, 8\n\t" "lxvd2x 52, 0, %[data]\n\t" +#ifdef __LITTLE_ENDIAN__ + "vperm 20, 20, 20, 9\n\t" +#endif /* __LITTLE_ENDIAN__ */ "addi %[data], %[data], 16\n\t" "vsldoi 21, 20, 20, 8\n\t" "lxvd2x 54, 0, %[data]\n\t" +#ifdef __LITTLE_ENDIAN__ + "vperm 22, 22, 22, 9\n\t" +#endif /* __LITTLE_ENDIAN__ */ "addi %[data], %[data], 16\n\t" "vsldoi 23, 22, 22, 8\n\t" "lxvd2x 56, 0, %[data]\n\t" +#ifdef __LITTLE_ENDIAN__ + "vperm 24, 24, 24, 9\n\t" +#endif /* __LITTLE_ENDIAN__ */ "addi %[data], %[data], 16\n\t" "vsldoi 25, 24, 24, 8\n\t" "lxvd2x 58, 0, %[data]\n\t" +#ifdef __LITTLE_ENDIAN__ + "vperm 26, 26, 26, 9\n\t" +#endif /* __LITTLE_ENDIAN__ */ "addi %[data], %[data], 16\n\t" "vsldoi 27, 26, 26, 8\n\t" "lxvd2x 60, 0, %[data]\n\t" +#ifdef __LITTLE_ENDIAN__ + "vperm 28, 28, 28, 9\n\t" +#endif /* __LITTLE_ENDIAN__ */ "addi %[data], %[data], 16\n\t" "vsldoi 29, 28, 28, 8\n\t" "lxvd2x 62, 0, %[data]\n\t" +#ifdef __LITTLE_ENDIAN__ + "vperm 30, 30, 30, 9\n\t" +#endif /* __LITTLE_ENDIAN__ */ "addi %[data], %[data], 16\n\t" "vsldoi 31, 30, 30, 8\n\t" /* Preload first key */ From b411f09dedff7390f20e31a4b0010c505311bd76 Mon Sep 17 00:00:00 2001 From: kaleb-himes Date: Wed, 4 Nov 2026 13:23:08 -0700 Subject: [PATCH 2/3] sha256: reverse Transform block words for PPC64 asm on little-endian --- wolfcrypt/src/sha256.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/wolfcrypt/src/sha256.c b/wolfcrypt/src/sha256.c index fe5cbc2a833..0e2d3eb8d09 100644 --- a/wolfcrypt/src/sha256.c +++ b/wolfcrypt/src/sha256.c @@ -2585,7 +2585,8 @@ static WC_INLINE int Transform_Sha256_Len(wc_Sha256* sha256, const byte* data, return BAD_FUNC_ARG; } - #if defined(WOLFSSL_ARMASM) || defined(WOLFSSL_RISCV_ASM) + #if defined(WOLFSSL_ARMASM) || defined(WOLFSSL_RISCV_ASM) || \ + (defined(WOLFSSL_PPC64_ASM) && defined(LITTLE_ENDIAN_ORDER)) #ifdef __aarch64__ if (Transform_Sha256_Len_p == Transform_Sha256_Len) { return Transform_Sha256(sha256, data); From 3471f226f2f356e51c9174866bd68097d09a750c Mon Sep 17 00:00:00 2001 From: kaleb-himes Date: Thu, 5 Nov 2026 04:34:55 -0700 Subject: [PATCH 3/3] pwdbased: run scryptSalsa on a word32 copy in scryptBlockMix --- wolfcrypt/src/pwdbased.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/wolfcrypt/src/pwdbased.c b/wolfcrypt/src/pwdbased.c index 206da4b079c..399d2dfdb76 100644 --- a/wolfcrypt/src/pwdbased.c +++ b/wolfcrypt/src/pwdbased.c @@ -937,6 +937,7 @@ static void scryptBlockMix(byte* b, byte* y, int r) { #ifdef WORD64_AVAILABLE word64 x[8]; + word32 x32[16]; word64* b64 = (word64*)b; word64* y64 = (word64*)y; #else @@ -955,12 +956,15 @@ static void scryptBlockMix(byte* b, byte* y, int r) #ifdef WORD64_AVAILABLE for (j = 0; j < 8; j++) x[j] ^= b64[i * 8 + j]; - + /* C11 6.5p7: x is word64, so run the word32 Salsa on a word32 copy. */ + XMEMCPY(x32, x, sizeof(x32)); + scryptSalsa(x32, x32); + XMEMCPY(x, x32, sizeof(x)); #else for (j = 0; j < 16; j++) x[j] ^= b32[i * 16 + j]; + scryptSalsa(x, x); #endif - scryptSalsa((word32*)x, (word32*)x); XMEMCPY(y + i * 64, x, sizeof(x)); } /* Step 3. */