Add helper support for the Octeon HSH hash selectors. This includes the
base HSH data/IV windows, MD5, SHA1, SHA256, and SHA512 transform paths,
and the shared HSH/SHA512 register-window readback and write operations.
The SHA512 path shares the wide HSH register bank with SHA3, SNOW3G, and
ZUC. Keep the aliased readback and write paths centralized so selector
decode can route register accesses through these helpers when side
effects are required.
Signed-off-by: James Hilliard <[email protected]>
---
Changes v13 -> v14:
- Keep HSH narrow DAT/IV state updates in the low 32-bit halves of the
architectural HSH register bank so paired selector transfers preserve
the wide shared-window state.
Changes v10 -> v13:
- Keep the 0x0057 SDK compatibility path as an explicit STARTSHA1
compatibility helper instead of a generic STARTSHA name.
Changes v9 -> v10:
- Remove references to shared-mode tracking; aliased state is kept in the
architectural HSH register banks.
Changes v8 -> v9:
- Split HSH/SHA helpers into their own COP2 helper patch.
- Replace generic selector dispatch with per-operation HSH helpers.
- Keep shared-window readback and write helpers grouped with HSH.
- Add matching helper.h declarations with the helper implementation.
---
target/mips/helper.h | 5 +
target/mips/tcg/octeon_crypto.c | 375 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 380 insertions(+)
diff --git a/target/mips/helper.h b/target/mips/helper.h
index 71b7a2b30e..834f2d0769 100644
--- a/target/mips/helper.h
+++ b/target/mips/helper.h
@@ -69,6 +69,11 @@ DEF_HELPER_2(octeon_cp2_mt_des3_dec, void, env, i64)
DEF_HELPER_2(octeon_cp2_mt_camellia_fl, void, env, i64)
DEF_HELPER_2(octeon_cp2_mt_camellia_flinv, void, env, i64)
DEF_HELPER_2(octeon_cp2_mt_camellia_round, void, env, i64)
+DEF_HELPER_2(octeon_cp2_mt_hsh_startsha1_compat, void, env, i64)
+DEF_HELPER_2(octeon_cp2_mt_hsh_startmd5, void, env, i64)
+DEF_HELPER_2(octeon_cp2_mt_hsh_startsha256, void, env, i64)
+DEF_HELPER_2(octeon_cp2_mt_hsh_startsha, void, env, i64)
+DEF_HELPER_2(octeon_cp2_mt_hsh_startsha512, void, env, i64)
/* microMIPS functions */
DEF_HELPER_4(lwm, void, env, tl, tl, i32)
diff --git a/target/mips/tcg/octeon_crypto.c b/target/mips/tcg/octeon_crypto.c
index 67959618cc..9523c84667 100644
--- a/target/mips/tcg/octeon_crypto.c
+++ b/target/mips/tcg/octeon_crypto.c
@@ -153,6 +153,348 @@ static void octeon_gfm_mul64_uia2(const uint64_t x[2],
const uint64_t y[2],
out[1] = revbit64(res);
}
+static inline uint32_t octeon_hsh_get32(const uint64_t *regs,
+ unsigned int index)
+{
+ return regs[index];
+}
+
+static inline void octeon_hsh_set32(uint64_t *regs, unsigned int index,
+ uint32_t value)
+{
+ regs[index] = (regs[index] & ~(uint64_t)UINT32_MAX) | value;
+}
+
+static inline void octeon_hsh_set_pair(uint64_t *regs, unsigned int index,
+ uint64_t value)
+{
+ octeon_hsh_set32(regs, index * 2, value >> 32);
+ octeon_hsh_set32(regs, index * 2 + 1, value);
+}
+
+static void octeon_md5_transform(MIPSOcteonCryptoState *crypto)
+{
+ static const uint32_t k[64] = {
+ 0xd76aa478U, 0xe8c7b756U, 0x242070dbU, 0xc1bdceeeU,
+ 0xf57c0fafU, 0x4787c62aU, 0xa8304613U, 0xfd469501U,
+ 0x698098d8U, 0x8b44f7afU, 0xffff5bb1U, 0x895cd7beU,
+ 0x6b901122U, 0xfd987193U, 0xa679438eU, 0x49b40821U,
+ 0xf61e2562U, 0xc040b340U, 0x265e5a51U, 0xe9b6c7aaU,
+ 0xd62f105dU, 0x02441453U, 0xd8a1e681U, 0xe7d3fbc8U,
+ 0x21e1cde6U, 0xc33707d6U, 0xf4d50d87U, 0x455a14edU,
+ 0xa9e3e905U, 0xfcefa3f8U, 0x676f02d9U, 0x8d2a4c8aU,
+ 0xfffa3942U, 0x8771f681U, 0x6d9d6122U, 0xfde5380cU,
+ 0xa4beea44U, 0x4bdecfa9U, 0xf6bb4b60U, 0xbebfbc70U,
+ 0x289b7ec6U, 0xeaa127faU, 0xd4ef3085U, 0x04881d05U,
+ 0xd9d4d039U, 0xe6db99e5U, 0x1fa27cf8U, 0xc4ac5665U,
+ 0xf4292244U, 0x432aff97U, 0xab9423a7U, 0xfc93a039U,
+ 0x655b59c3U, 0x8f0ccc92U, 0xffeff47dU, 0x85845dd1U,
+ 0x6fa87e4fU, 0xfe2ce6e0U, 0xa3014314U, 0x4e0811a1U,
+ 0xf7537e82U, 0xbd3af235U, 0x2ad7d2bbU, 0xeb86d391U,
+ };
+ static const uint8_t s[64] = {
+ 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
+ 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
+ 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
+ 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21,
+ };
+ uint32_t m[16];
+ uint32_t a, b, c, d;
+ uint32_t aa, bb, cc, dd;
+ int i;
+
+ for (i = 0; i < 16; i++) {
+ m[i] = bswap32(octeon_hsh_get32(crypto->hsh_dat, i));
+ }
+
+ a = bswap32(octeon_hsh_get32(crypto->hsh_iv, 0));
+ b = bswap32(octeon_hsh_get32(crypto->hsh_iv, 1));
+ c = bswap32(octeon_hsh_get32(crypto->hsh_iv, 2));
+ d = bswap32(octeon_hsh_get32(crypto->hsh_iv, 3));