@@ -2172,6 +2172,92 @@ void helper_td(CPUPPCState *env, target_ulong arg1, target_ulong arg2,
21722172#endif
21732173#endif
21742174
2175+ static uint32_t helper_SIMON_LIKE_32_64 (uint32_t x , uint64_t key , uint32_t lane )
2176+ {
2177+ uint32_t c = 0xfffc ;
2178+ uint64_t z0 = 0xfa2561cdf44ac398 ;
2179+ uint16_t z = 0 , temp ;
2180+ uint16_t k [32 ], eff_k [32 ], xleft [33 ], xright [33 ], fxleft [32 ];
2181+
2182+ for (int i = 3 ; i >= 0 ; i -- ) {
2183+ k [i ] = key & 0xffff ;
2184+ key >>= 16 ;
2185+ }
2186+ xleft [0 ] = x & 0xffff ;
2187+ xright [0 ] = (x >> 16 ) & 0xffff ;
2188+
2189+ for (int i = 0 ; i < 28 ; i ++ ) {
2190+ z |= ((z0 >> (63 - i )) & 1 ) << 48 ;
2191+ temp = ror16 (k [i + 3 ], 3 ) ^ k [i + 1 ];
2192+ k [i + 4 ] = c ^ z ^ k [i ] ^ temp ^ ror16 (temp , 1 );
2193+ }
2194+
2195+ for (int i = 0 ; i < 8 ; i ++ )
2196+ {
2197+ eff_k [4 * i + 0 ] = k [4 * i + ((0 + lane ) % 4 )];
2198+ eff_k [4 * i + 1 ] = k [4 * i + ((1 + lane ) % 4 )];
2199+ eff_k [4 * i + 2 ] = k [4 * i + ((2 + lane ) % 4 )];
2200+ eff_k [4 * i + 3 ] = k [4 * i + ((3 + lane ) % 4 )];
2201+ }
2202+
2203+ for (int i = 0 ; i < 32 ; i ++ )
2204+ {
2205+ fxleft [i ] = (rol16 (xleft [i ], 1 ) &
2206+ rol16 (xleft [i ], 8 )) ^ rol16 (xleft [i ], 2 );
2207+ xleft [i + 1 ] = xright [i ] ^ fxleft [i ] ^ eff_k [i ];
2208+ xright [i + 1 ] = xleft [i ];
2209+ }
2210+
2211+ return (((uint32_t )xright [32 ]) << 16 ) | xleft [32 ];
2212+ }
2213+
2214+ /* TODO: check this implementation correctness; make it better */
2215+ static uint64_t hash_digest (uint64_t ra , uint64_t rb , uint64_t key )
2216+ {
2217+ uint64_t stage0_h = 0ULL , stage0_l = 0ULL ;
2218+ uint64_t stage1_h , stage1_l ;
2219+
2220+ for (int i = 0 ; i < 4 ; i ++ ) {
2221+ stage0_h |= ror64 (rb & 0xff , 8 * (2 * i + 1 ));
2222+ stage0_h |= ((ra >> 32 ) & 0xff ) << (8 * 2 * i );
2223+ stage0_l |= ror64 ((rb >> 32 ) & 0xff , 8 * (2 * i + 1 ));
2224+ stage0_l |= (ra & 0xff ) << (8 * 2 * i );
2225+ rb >>= 8 ;
2226+ ra >>= 8 ;
2227+ }
2228+
2229+ stage1_h = (uint64_t )helper_SIMON_LIKE_32_64 (stage0_h >> 32 , key , 0 ) << 32 ;
2230+ stage1_h |= helper_SIMON_LIKE_32_64 (stage0_h , key , 1 );
2231+ stage1_l = (uint64_t )helper_SIMON_LIKE_32_64 (stage0_l >> 32 , key , 2 ) << 32 ;
2232+ stage1_l |= helper_SIMON_LIKE_32_64 (stage0_l , key , 3 );
2233+
2234+ return (stage1_h ^ stage1_l );
2235+ }
2236+
2237+ #define HELPER_HASH (op , key , store ) \
2238+ void helper_##op(CPUPPCState *env, target_ulong ea, target_ulong ra, \
2239+ target_ulong rb) \
2240+ { \
2241+ uint64_t chash = hash_digest(ra, rb, key), lhash; \
2242+ \
2243+ if (store) { \
2244+ cpu_stq_data_ra(env, ea, chash, GETPC()); \
2245+ } \
2246+ else { \
2247+ lhash = cpu_ldq_data_ra(env, ea, GETPC()); \
2248+ if (lhash != chash) { \
2249+ /* hashes don't match, trap */ \
2250+ raise_exception_err_ra (env , POWERPC_EXCP_PROGRAM , \
2251+ POWERPC_EXCP_TRAP , GETPC ()); \
2252+ } \
2253+ } \
2254+ }
2255+
2256+ HELPER_HASH (HASHST , env -> spr [SPR_POWER_HASHKEYR ], true)
2257+ HELPER_HASH (HASHCHK , env -> spr [SPR_POWER_HASHKEYR ], false)
2258+ HELPER_HASH (HASHSTP , env -> spr [SPR_POWER_HASHPKEYR ], true)
2259+ HELPER_HASH (HASHCHKP , env -> spr [SPR_POWER_HASHPKEYR ], false)
2260+
21752261#if !defined(CONFIG_USER_ONLY )
21762262
21772263#ifdef CONFIG_TCG
0 commit comments