Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions wolfcrypt/src/port/ppc64/ppc64-sha256-asm.S
Original file line number Diff line number Diff line change
Expand Up @@ -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
Comment on lines +3497 to +3504

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 On ppc64le POWER8+ crypto builds with OPENSSL_EXTRA, wc_Sha256Transform and wc_Sha512Transform now return wrong digests; on the base branch they are correct. The new vperm makes the crypto transforms read a big-endian byte stream. The single-block wrappers still pass little-endian native words. Fix: on PPC64 little-endian, have both wrappers give the asm a big-endian stream (byte-reverse into a temp buffer in sha256.c, and skip the ByteReverseWords64 in sha512.c), which covers the 2 sites listed. Same pattern at 2 sites (sha256.c:2616, sha512.c:2916).

Why this was flagged

wc_Sha256Transform (wolfcrypt/src/sha256.c:2616) passes the caller's block straight to Transform_Sha256 -> SHA256_TRANSFORM_LEN -> Transform_Sha256_Len_crypto (sha256.c:1350). On little-endian its contract is native 32-bit words: test_wc_Sha256Transform feeds "\x80\x63\x62\x61..." and expects SHA-256("abc"). Before this PR, lxvw4x loaded those words natively, so POWER8+ gave the right answer. After this PR the vperm at ppc64-sha256-asm.S:3504 (and its _c.c twin) byte-swaps every word, so the result is wrong. wc_Sha512Transform (sha512.c:2916) byte-reverses data with ByteReverseWords64 into native words and then calls Transform_Sha512 -> Transform_Sha512_Len_crypto (sha512.c:2928/1892). Before, lxvd2x consumed those words correctly. Now the new vperm in ppc64-sha512-asm.S reverses them a second time. The result: SHA256_Transform/SHA512_Transform (src/ssl_crypto.c:489, 629, 706, 785) and test_wc_Sha256Transform/test_wc_Sha512Transform fail on POWER8+ ppc64le. The PR description calls the wrappers a separate fix, but there the crypto path worked and this PR newly breaks it.

Verification: wc_Sha256Transform (wolfcrypt/src/sha256.c:2616) passes the caller's block as-is to Transform_Sha256_Len_crypto. On base, lxvw4x gives W0 = 0x61626380, so the result is correct. After the PR, vperm 16, 16, 16, 9 byte-swaps every word, so W0 becomes 0x80636261 and the digest is wrong. wc_Sha512Transform (sha512.c:2911-2928) regresses the same way.

#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
Expand Down
17 changes: 17 additions & 0 deletions wolfcrypt/src/port/ppc64/ppc64-sha256-asm_c.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
29 changes: 29 additions & 0 deletions wolfcrypt/src/port/ppc64/ppc64-sha512-asm.S
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
29 changes: 29 additions & 0 deletions wolfcrypt/src/port/ppc64/ppc64-sha512-asm_c.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
Loading