mirror of
https://github.com/qemu/qemu.git
synced 2026-07-08 17:56:38 +00:00
target/mips: add Octeon SHA3 COP2 helpers
Add the Octeon SHA3 helper operations for the architectural 25-lane Keccak state view and implement the Keccak-f[1600] permutation used by the STARTOP selector. The simple SHA3 DAT register moves and XORDAT selectors are decoded as direct TCG transfers in the selector decode patch. This helper patch only keeps the side-effecting SHA3 operation support. Signed-off-by: James Hilliard <james.hilliard1@gmail.com> Message-ID: <20260608-mips-octeon-missing-insns-v2-v16-5-daef7a0d8b04@gmail.com> Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
This commit is contained in:
committed by
Philippe Mathieu-Daudé
parent
c69401bbf6
commit
20d1f0e842
@@ -47,6 +47,7 @@ DEF_HELPER_2(octeon_cp2_mt_gfm_mul_reflect1, void, env, i64)
|
||||
DEF_HELPER_2(octeon_cp2_mt_gfm_xor0_reflect, void, env, i64)
|
||||
DEF_HELPER_2(octeon_cp2_mt_gfm_xormul1_reflect, void, env, i64)
|
||||
DEF_HELPER_2(octeon_cp2_mt_gfm_xormul1, void, env, i64)
|
||||
DEF_HELPER_1(octeon_cp2_mt_sha3_startop, void, env)
|
||||
|
||||
/* microMIPS functions */
|
||||
DEF_HELPER_4(lwm, void, env, tl, tl, i32)
|
||||
|
||||
@@ -153,6 +153,94 @@ static void octeon_gfm_mul64_uia2(const uint64_t x[2], const uint64_t y[2],
|
||||
out[1] = revbit64(res);
|
||||
}
|
||||
|
||||
static const uint64_t octeon_sha3_round_constants[24] = {
|
||||
0x0000000000000001ULL, 0x0000000000008082ULL,
|
||||
0x800000000000808aULL, 0x8000000080008000ULL,
|
||||
0x000000000000808bULL, 0x0000000080000001ULL,
|
||||
0x8000000080008081ULL, 0x8000000000008009ULL,
|
||||
0x000000000000008aULL, 0x0000000000000088ULL,
|
||||
0x0000000080008009ULL, 0x000000008000000aULL,
|
||||
0x000000008000808bULL, 0x800000000000008bULL,
|
||||
0x8000000000008089ULL, 0x8000000000008003ULL,
|
||||
0x8000000000008002ULL, 0x8000000000000080ULL,
|
||||
0x000000000000800aULL, 0x800000008000000aULL,
|
||||
0x8000000080008081ULL, 0x8000000000008080ULL,
|
||||
0x0000000080000001ULL, 0x8000000080008008ULL,
|
||||
};
|
||||
|
||||
static const uint8_t octeon_sha3_rotation_constants[24] = {
|
||||
1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14,
|
||||
27, 41, 56, 8, 25, 43, 62, 18, 39, 61, 20, 44,
|
||||
};
|
||||
|
||||
static const uint8_t octeon_sha3_pi_lanes[24] = {
|
||||
10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4,
|
||||
15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1,
|
||||
};
|
||||
|
||||
static uint64_t octeon_sha3_reg_to_lane(uint64_t value)
|
||||
{
|
||||
/*
|
||||
* The COP2 register interface is consumed by big-endian MIPS code as
|
||||
* 64-bit register values, while Keccak lanes are byte-little-endian.
|
||||
*/
|
||||
return bswap64(value);
|
||||
}
|
||||
|
||||
static uint64_t octeon_sha3_lane_to_reg(uint64_t value)
|
||||
{
|
||||
return bswap64(value);
|
||||
}
|
||||
|
||||
static void octeon_sha3_permute(MIPSOcteonCryptoState *crypto)
|
||||
{
|
||||
uint64_t state[25];
|
||||
|
||||
for (int i = 0; i < 25; i++) {
|
||||
state[i] = octeon_sha3_reg_to_lane(crypto->sha3_dat[i]);
|
||||
}
|
||||
|
||||
for (int round = 0; round < 24; round++) {
|
||||
uint64_t bc[5];
|
||||
uint64_t temp;
|
||||
|
||||
for (int x = 0; x < 5; x++) {
|
||||
bc[x] = state[x] ^ state[5 + x] ^ state[10 + x] ^
|
||||
state[15 + x] ^ state[20 + x];
|
||||
}
|
||||
for (int x = 0; x < 5; x++) {
|
||||
temp = bc[(x + 4) % 5] ^ rol64(bc[(x + 1) % 5], 1);
|
||||
for (int y = 0; y < 25; y += 5) {
|
||||
state[y + x] ^= temp;
|
||||
}
|
||||
}
|
||||
|
||||
temp = state[1];
|
||||
for (int i = 0; i < 24; i++) {
|
||||
uint64_t next = state[octeon_sha3_pi_lanes[i]];
|
||||
|
||||
state[octeon_sha3_pi_lanes[i]] =
|
||||
rol64(temp, octeon_sha3_rotation_constants[i]);
|
||||
temp = next;
|
||||
}
|
||||
|
||||
for (int y = 0; y < 25; y += 5) {
|
||||
for (int x = 0; x < 5; x++) {
|
||||
bc[x] = state[y + x];
|
||||
}
|
||||
for (int x = 0; x < 5; x++) {
|
||||
state[y + x] = bc[x] ^ ((~bc[(x + 1) % 5]) & bc[(x + 2) % 5]);
|
||||
}
|
||||
}
|
||||
|
||||
state[0] ^= octeon_sha3_round_constants[round];
|
||||
}
|
||||
|
||||
for (int i = 0; i < 25; i++) {
|
||||
crypto->sha3_dat[i] = octeon_sha3_lane_to_reg(state[i]);
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t helper_octeon_cp2_mf_crc_iv_reflect(CPUMIPSState *env)
|
||||
{
|
||||
return octeon_crc_reflect32_by_byte(env->octeon_crypto.crc_iv);
|
||||
@@ -222,6 +310,11 @@ void helper_octeon_cp2_mt_gfm_xormul1(CPUMIPSState *env, uint64_t value)
|
||||
octeon_gfm_xormul1_common(crypto, value);
|
||||
}
|
||||
|
||||
void helper_octeon_cp2_mt_sha3_startop(CPUMIPSState *env)
|
||||
{
|
||||
octeon_sha3_permute(&env->octeon_crypto);
|
||||
}
|
||||
|
||||
void helper_octeon_cp2_mt_crc_write_iv_reflect(CPUMIPSState *env,
|
||||
uint64_t value)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user