diff --git a/qemu/target-arm/crypto_helper.c b/qemu/target-arm/crypto_helper.c index 59988edd..48ade427 100644 --- a/qemu/target-arm/crypto_helper.c +++ b/qemu/target-arm/crypto_helper.c @@ -22,6 +22,14 @@ union CRYPTO_STATE { uint64_t l[2]; }; +#ifdef HOST_WORDS_BIGENDIAN +#define CR_ST_BYTE(state, i) (state.bytes[(15 - (i)) ^ 8]) +#define CR_ST_WORD(state, i) (state.words[(3 - (i)) ^ 2]) +#else +#define CR_ST_BYTE(state, i) (state.bytes[i]) +#define CR_ST_WORD(state, i) (state.words[i]) +#endif + void HELPER(crypto_aese)(CPUARMState *env, uint32_t rd, uint32_t rm, uint32_t decrypt) { @@ -45,7 +53,7 @@ void HELPER(crypto_aese)(CPUARMState *env, uint32_t rd, uint32_t rm, /* combine ShiftRows operation and sbox substitution */ for (i = 0; i < 16; i++) { - st.bytes[i] = sbox[decrypt][rk.bytes[shift[decrypt][i]]]; + CR_ST_BYTE(st, i) = sbox[decrypt][CR_ST_BYTE(rk, shift[decrypt][i])]; } env->vfp.regs[rd] = make_float64(st.l[0]); @@ -196,11 +204,11 @@ void HELPER(crypto_aesmc)(CPUARMState *env, uint32_t rd, uint32_t rm, assert(decrypt < 2); for (i = 0; i < 16; i += 4) { - st.words[i >> 2] = cpu_to_le32( - mc[decrypt][st.bytes[i]] ^ - rol32(mc[decrypt][st.bytes[i + 1]], 8) ^ - rol32(mc[decrypt][st.bytes[i + 2]], 16) ^ - rol32(mc[decrypt][st.bytes[i + 3]], 24)); + CR_ST_WORD(st, i >> 2) = + mc[decrypt][CR_ST_BYTE(st, i)] ^ + rol32(mc[decrypt][CR_ST_BYTE(st, i + 1)], 8) ^ + rol32(mc[decrypt][CR_ST_BYTE(st, i + 2)], 16) ^ + rol32(mc[decrypt][CR_ST_BYTE(st, i + 3)], 24); } env->vfp.regs[rd] = make_float64(st.l[0]); @@ -250,24 +258,25 @@ void HELPER(crypto_sha1_3reg)(CPUARMState *env, uint32_t rd, uint32_t rn, switch (op) { case 0: /* sha1c */ - t = cho(d.words[1], d.words[2], d.words[3]); + t = cho(CR_ST_WORD(d, 1), CR_ST_WORD(d, 2), CR_ST_WORD(d, 3)); break; case 1: /* sha1p */ - t = par(d.words[1], d.words[2], d.words[3]); + t = par(CR_ST_WORD(d, 1), CR_ST_WORD(d, 2), CR_ST_WORD(d, 3)); break; case 2: /* sha1m */ - t = maj(d.words[1], d.words[2], d.words[3]); + t = maj(CR_ST_WORD(d, 1), CR_ST_WORD(d, 2), CR_ST_WORD(d, 3)); break; default: g_assert_not_reached(); } - t += rol32(d.words[0], 5) + n.words[0] + m.words[i]; + t += rol32(CR_ST_WORD(d, 0), 5) + CR_ST_WORD(n, 0) + + CR_ST_WORD(m, i); - n.words[0] = d.words[3]; - d.words[3] = d.words[2]; - d.words[2] = ror32(d.words[1], 2); - d.words[1] = d.words[0]; - d.words[0] = t; + CR_ST_WORD(n, 0) = CR_ST_WORD(d, 3); + CR_ST_WORD(d, 3) = CR_ST_WORD(d, 2); + CR_ST_WORD(d, 2) = ror32(CR_ST_WORD(d, 1), 2); + CR_ST_WORD(d, 1) = CR_ST_WORD(d, 0); + CR_ST_WORD(d, 0) = t; } } env->vfp.regs[rd] = make_float64(d.l[0]); @@ -280,8 +289,8 @@ void HELPER(crypto_sha1h)(CPUARMState *env, uint32_t rd, uint32_t rm) m.l[0] = float64_val(env->vfp.regs[rm]); m.l[1] = float64_val(env->vfp.regs[rm + 1]); - m.words[0] = ror32(m.words[0], 2); - m.words[1] = m.words[2] = m.words[3] = 0; + CR_ST_WORD(m, 0) = ror32(CR_ST_WORD(m, 0), 2); + CR_ST_WORD(m, 1) = CR_ST_WORD(m, 2) = CR_ST_WORD(m, 3) = 0; env->vfp.regs[rd] = make_float64(m.l[0]); env->vfp.regs[rd + 1] = make_float64(m.l[1]); @@ -296,10 +305,10 @@ void HELPER(crypto_sha1su1)(CPUARMState *env, uint32_t rd, uint32_t rm) m.l[0] = float64_val(env->vfp.regs[rm]); m.l[1] = float64_val(env->vfp.regs[rm + 1]); - d.words[0] = rol32(d.words[0] ^ m.words[1], 1); - d.words[1] = rol32(d.words[1] ^ m.words[2], 1); - d.words[2] = rol32(d.words[2] ^ m.words[3], 1); - d.words[3] = rol32(d.words[3] ^ d.words[0], 1); + CR_ST_WORD(d, 0) = rol32(CR_ST_WORD(d, 0) ^ CR_ST_WORD(m, 1), 1); + CR_ST_WORD(d, 1) = rol32(CR_ST_WORD(d, 1) ^ CR_ST_WORD(m, 2), 1); + CR_ST_WORD(d, 2) = rol32(CR_ST_WORD(d, 2) ^ CR_ST_WORD(m, 3), 1); + CR_ST_WORD(d, 3) = rol32(CR_ST_WORD(d, 3) ^ CR_ST_WORD(d, 0), 1); env->vfp.regs[rd] = make_float64(d.l[0]); env->vfp.regs[rd + 1] = make_float64(d.l[1]); @@ -345,20 +354,22 @@ void HELPER(crypto_sha256h)(CPUARMState *env, uint32_t rd, uint32_t rn, m.l[1] = float64_val(env->vfp.regs[rm + 1]); for (i = 0; i < 4; i++) { - uint32_t t = cho(n.words[0], n.words[1], n.words[2]) + n.words[3] - + S1(n.words[0]) + m.words[i]; + uint32_t t = cho(CR_ST_WORD(n, 0), CR_ST_WORD(n, 1), CR_ST_WORD(n, 2)) + + CR_ST_WORD(n, 3) + S1(CR_ST_WORD(n, 0)) + + CR_ST_WORD(m, i); - n.words[3] = n.words[2]; - n.words[2] = n.words[1]; - n.words[1] = n.words[0]; - n.words[0] = d.words[3] + t; + CR_ST_WORD(n, 3) = CR_ST_WORD(n, 2); + CR_ST_WORD(n, 2) = CR_ST_WORD(n, 1); + CR_ST_WORD(n, 1) = CR_ST_WORD(n, 0); + CR_ST_WORD(n, 0) = CR_ST_WORD(d, 3) + t; - t += maj(d.words[0], d.words[1], d.words[2]) + S0(d.words[0]); + t += maj(CR_ST_WORD(d, 0), CR_ST_WORD(d, 1), CR_ST_WORD(d, 2)) + + S0(CR_ST_WORD(d, 0)); - d.words[3] = d.words[2]; - d.words[2] = d.words[1]; - d.words[1] = d.words[0]; - d.words[0] = t; + CR_ST_WORD(d, 3) = CR_ST_WORD(d, 2); + CR_ST_WORD(d, 2) = CR_ST_WORD(d, 1); + CR_ST_WORD(d, 1) = CR_ST_WORD(d, 0); + CR_ST_WORD(d, 0) = t; } env->vfp.regs[rd] = make_float64(d.l[0]); @@ -381,13 +392,14 @@ void HELPER(crypto_sha256h2)(CPUARMState *env, uint32_t rd, uint32_t rn, m.l[1] = float64_val(env->vfp.regs[rm + 1]); for (i = 0; i < 4; i++) { - uint32_t t = cho(d.words[0], d.words[1], d.words[2]) + d.words[3] - + S1(d.words[0]) + m.words[i]; + uint32_t t = cho(CR_ST_WORD(d, 0), CR_ST_WORD(d, 1), CR_ST_WORD(d, 2)) + + CR_ST_WORD(d, 3) + S1(CR_ST_WORD(d, 0)) + + CR_ST_WORD(m, i); - d.words[3] = d.words[2]; - d.words[2] = d.words[1]; - d.words[1] = d.words[0]; - d.words[0] = n.words[3 - i] + t; + CR_ST_WORD(d, 3) = CR_ST_WORD(d, 2); + CR_ST_WORD(d, 2) = CR_ST_WORD(d, 1); + CR_ST_WORD(d, 1) = CR_ST_WORD(d, 0); + CR_ST_WORD(d, 0) = CR_ST_WORD(n, 3 - i) + t; } env->vfp.regs[rd] = make_float64(d.l[0]); @@ -403,10 +415,10 @@ void HELPER(crypto_sha256su0)(CPUARMState *env, uint32_t rd, uint32_t rm) m.l[0] = float64_val(env->vfp.regs[rm]); m.l[1] = float64_val(env->vfp.regs[rm + 1]); - d.words[0] += s0(d.words[1]); - d.words[1] += s0(d.words[2]); - d.words[2] += s0(d.words[3]); - d.words[3] += s0(m.words[0]); + CR_ST_WORD(d, 0) += s0(CR_ST_WORD(d, 1)); + CR_ST_WORD(d, 1) += s0(CR_ST_WORD(d, 2)); + CR_ST_WORD(d, 2) += s0(CR_ST_WORD(d, 3)); + CR_ST_WORD(d, 3) += s0(CR_ST_WORD(m, 0)); env->vfp.regs[rd] = make_float64(d.l[0]); env->vfp.regs[rd + 1] = make_float64(d.l[1]); @@ -425,10 +437,10 @@ void HELPER(crypto_sha256su1)(CPUARMState *env, uint32_t rd, uint32_t rn, m.l[0] = float64_val(env->vfp.regs[rm]); m.l[1] = float64_val(env->vfp.regs[rm + 1]); - d.words[0] += s1(m.words[2]) + n.words[1]; - d.words[1] += s1(m.words[3]) + n.words[2]; - d.words[2] += s1(d.words[0]) + n.words[3]; - d.words[3] += s1(d.words[1]) + m.words[0]; + CR_ST_WORD(d, 0) += s1(CR_ST_WORD(m, 2)) + CR_ST_WORD(n, 1); + CR_ST_WORD(d, 1) += s1(CR_ST_WORD(m, 3)) + CR_ST_WORD(n, 2); + CR_ST_WORD(d, 2) += s1(CR_ST_WORD(d, 0)) + CR_ST_WORD(n, 3); + CR_ST_WORD(d, 3) += s1(CR_ST_WORD(d, 1)) + CR_ST_WORD(m, 0); env->vfp.regs[rd] = make_float64(d.l[0]); env->vfp.regs[rd + 1] = make_float64(d.l[1]);