target/arm: implement SM4 instructions

This implements emulation of the new SM4 instructions that have
been added as an optional extension to the ARMv8 Crypto Extensions
in ARM v8.2.

Backports commit b6577bcd251ca0d57ae1de149e3c706b38f21587 from qemu
This commit is contained in:
Ard Biesheuvel 2018-03-07 08:56:16 -05:00 committed by Lioncash
parent 78d15a9cd0
commit 85e6d710e4
No known key found for this signature in database
GPG Key ID: 4E3C3CC1031BA9C7
18 changed files with 143 additions and 0 deletions

View File

@ -1604,6 +1604,8 @@
#define helper_crypto_sm3partw1 helper_crypto_sm3partw1_aarch64
#define helper_crypto_sm3partw2 helper_crypto_sm3partw2_aarch64
#define helper_crypto_sm3tt helper_crypto_sm3tt_aarch64
#define helper_crypto_sm4e helper_crypto_sm4e_aarch64
#define helper_crypto_sm4ekey helper_crypto_sm4ekey_aarch64
#define helper_dc_zva helper_dc_zva_aarch64
#define helper_div_i32 helper_div_i32_aarch64
#define helper_div_i64 helper_div_i64_aarch64

View File

@ -1604,6 +1604,8 @@
#define helper_crypto_sm3partw1 helper_crypto_sm3partw1_aarch64eb
#define helper_crypto_sm3partw2 helper_crypto_sm3partw2_aarch64eb
#define helper_crypto_sm3tt helper_crypto_sm3tt_aarch64eb
#define helper_crypto_sm4e helper_crypto_sm4e_aarch64eb
#define helper_crypto_sm4ekey helper_crypto_sm4ekey_aarch64eb
#define helper_dc_zva helper_dc_zva_aarch64eb
#define helper_div_i32 helper_div_i32_aarch64eb
#define helper_div_i64 helper_div_i64_aarch64eb

View File

@ -1604,6 +1604,8 @@
#define helper_crypto_sm3partw1 helper_crypto_sm3partw1_arm
#define helper_crypto_sm3partw2 helper_crypto_sm3partw2_arm
#define helper_crypto_sm3tt helper_crypto_sm3tt_arm
#define helper_crypto_sm4e helper_crypto_sm4e_arm
#define helper_crypto_sm4ekey helper_crypto_sm4ekey_arm
#define helper_dc_zva helper_dc_zva_arm
#define helper_div_i32 helper_div_i32_arm
#define helper_div_i64 helper_div_i64_arm

View File

@ -1604,6 +1604,8 @@
#define helper_crypto_sm3partw1 helper_crypto_sm3partw1_armeb
#define helper_crypto_sm3partw2 helper_crypto_sm3partw2_armeb
#define helper_crypto_sm3tt helper_crypto_sm3tt_armeb
#define helper_crypto_sm4e helper_crypto_sm4e_armeb
#define helper_crypto_sm4ekey helper_crypto_sm4ekey_armeb
#define helper_dc_zva helper_dc_zva_armeb
#define helper_div_i32 helper_div_i32_armeb
#define helper_div_i64 helper_div_i64_armeb

View File

@ -1610,6 +1610,8 @@ symbols = (
'helper_crypto_sm3partw1',
'helper_crypto_sm3partw2',
'helper_crypto_sm3tt',
'helper_crypto_sm4e',
'helper_crypto_sm4ekey',
'helper_dc_zva',
'helper_div_i32',
'helper_div_i64',

View File

@ -1604,6 +1604,8 @@
#define helper_crypto_sm3partw1 helper_crypto_sm3partw1_m68k
#define helper_crypto_sm3partw2 helper_crypto_sm3partw2_m68k
#define helper_crypto_sm3tt helper_crypto_sm3tt_m68k
#define helper_crypto_sm4e helper_crypto_sm4e_m68k
#define helper_crypto_sm4ekey helper_crypto_sm4ekey_m68k
#define helper_dc_zva helper_dc_zva_m68k
#define helper_div_i32 helper_div_i32_m68k
#define helper_div_i64 helper_div_i64_m68k

View File

@ -1604,6 +1604,8 @@
#define helper_crypto_sm3partw1 helper_crypto_sm3partw1_mips
#define helper_crypto_sm3partw2 helper_crypto_sm3partw2_mips
#define helper_crypto_sm3tt helper_crypto_sm3tt_mips
#define helper_crypto_sm4e helper_crypto_sm4e_mips
#define helper_crypto_sm4ekey helper_crypto_sm4ekey_mips
#define helper_dc_zva helper_dc_zva_mips
#define helper_div_i32 helper_div_i32_mips
#define helper_div_i64 helper_div_i64_mips

View File

@ -1604,6 +1604,8 @@
#define helper_crypto_sm3partw1 helper_crypto_sm3partw1_mips64
#define helper_crypto_sm3partw2 helper_crypto_sm3partw2_mips64
#define helper_crypto_sm3tt helper_crypto_sm3tt_mips64
#define helper_crypto_sm4e helper_crypto_sm4e_mips64
#define helper_crypto_sm4ekey helper_crypto_sm4ekey_mips64
#define helper_dc_zva helper_dc_zva_mips64
#define helper_div_i32 helper_div_i32_mips64
#define helper_div_i64 helper_div_i64_mips64

View File

@ -1604,6 +1604,8 @@
#define helper_crypto_sm3partw1 helper_crypto_sm3partw1_mips64el
#define helper_crypto_sm3partw2 helper_crypto_sm3partw2_mips64el
#define helper_crypto_sm3tt helper_crypto_sm3tt_mips64el
#define helper_crypto_sm4e helper_crypto_sm4e_mips64el
#define helper_crypto_sm4ekey helper_crypto_sm4ekey_mips64el
#define helper_dc_zva helper_dc_zva_mips64el
#define helper_div_i32 helper_div_i32_mips64el
#define helper_div_i64 helper_div_i64_mips64el

View File

@ -1604,6 +1604,8 @@
#define helper_crypto_sm3partw1 helper_crypto_sm3partw1_mipsel
#define helper_crypto_sm3partw2 helper_crypto_sm3partw2_mipsel
#define helper_crypto_sm3tt helper_crypto_sm3tt_mipsel
#define helper_crypto_sm4e helper_crypto_sm4e_mipsel
#define helper_crypto_sm4ekey helper_crypto_sm4ekey_mipsel
#define helper_dc_zva helper_dc_zva_mipsel
#define helper_div_i32 helper_div_i32_mipsel
#define helper_div_i64 helper_div_i64_mipsel

View File

@ -1604,6 +1604,8 @@
#define helper_crypto_sm3partw1 helper_crypto_sm3partw1_powerpc
#define helper_crypto_sm3partw2 helper_crypto_sm3partw2_powerpc
#define helper_crypto_sm3tt helper_crypto_sm3tt_powerpc
#define helper_crypto_sm4e helper_crypto_sm4e_powerpc
#define helper_crypto_sm4ekey helper_crypto_sm4ekey_powerpc
#define helper_dc_zva helper_dc_zva_powerpc
#define helper_div_i32 helper_div_i32_powerpc
#define helper_div_i64 helper_div_i64_powerpc

View File

@ -1604,6 +1604,8 @@
#define helper_crypto_sm3partw1 helper_crypto_sm3partw1_sparc
#define helper_crypto_sm3partw2 helper_crypto_sm3partw2_sparc
#define helper_crypto_sm3tt helper_crypto_sm3tt_sparc
#define helper_crypto_sm4e helper_crypto_sm4e_sparc
#define helper_crypto_sm4ekey helper_crypto_sm4ekey_sparc
#define helper_dc_zva helper_dc_zva_sparc
#define helper_div_i32 helper_div_i32_sparc
#define helper_div_i64 helper_div_i64_sparc

View File

@ -1604,6 +1604,8 @@
#define helper_crypto_sm3partw1 helper_crypto_sm3partw1_sparc64
#define helper_crypto_sm3partw2 helper_crypto_sm3partw2_sparc64
#define helper_crypto_sm3tt helper_crypto_sm3tt_sparc64
#define helper_crypto_sm4e helper_crypto_sm4e_sparc64
#define helper_crypto_sm4ekey helper_crypto_sm4ekey_sparc64
#define helper_dc_zva helper_dc_zva_sparc64
#define helper_div_i32 helper_div_i32_sparc64
#define helper_div_i64 helper_div_i64_sparc64

View File

@ -1320,6 +1320,7 @@ enum arm_features {
ARM_FEATURE_V8_SHA512, /* implements SHA512 part of v8 Crypto Extensions */
ARM_FEATURE_V8_SHA3, /* implements SHA3 part of v8 Crypto Extensions */
ARM_FEATURE_V8_SM3, /* implements SM3 part of v8 Crypto Extensions */
ARM_FEATURE_V8_SM4, /* implements SM4 part of v8 Crypto Extensions */
};
static inline int arm_feature(CPUARMState *env, int feature)

View File

@ -675,3 +675,106 @@ void HELPER(crypto_sm3tt)(void *vd, void *vn, void *vm, uint32_t imm2,
rd[0] = d.l[0];
rd[1] = d.l[1];
}
static uint8_t const sm4_sbox[] = {
0xd6, 0x90, 0xe9, 0xfe, 0xcc, 0xe1, 0x3d, 0xb7,
0x16, 0xb6, 0x14, 0xc2, 0x28, 0xfb, 0x2c, 0x05,
0x2b, 0x67, 0x9a, 0x76, 0x2a, 0xbe, 0x04, 0xc3,
0xaa, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99,
0x9c, 0x42, 0x50, 0xf4, 0x91, 0xef, 0x98, 0x7a,
0x33, 0x54, 0x0b, 0x43, 0xed, 0xcf, 0xac, 0x62,
0xe4, 0xb3, 0x1c, 0xa9, 0xc9, 0x08, 0xe8, 0x95,
0x80, 0xdf, 0x94, 0xfa, 0x75, 0x8f, 0x3f, 0xa6,
0x47, 0x07, 0xa7, 0xfc, 0xf3, 0x73, 0x17, 0xba,
0x83, 0x59, 0x3c, 0x19, 0xe6, 0x85, 0x4f, 0xa8,
0x68, 0x6b, 0x81, 0xb2, 0x71, 0x64, 0xda, 0x8b,
0xf8, 0xeb, 0x0f, 0x4b, 0x70, 0x56, 0x9d, 0x35,
0x1e, 0x24, 0x0e, 0x5e, 0x63, 0x58, 0xd1, 0xa2,
0x25, 0x22, 0x7c, 0x3b, 0x01, 0x21, 0x78, 0x87,
0xd4, 0x00, 0x46, 0x57, 0x9f, 0xd3, 0x27, 0x52,
0x4c, 0x36, 0x02, 0xe7, 0xa0, 0xc4, 0xc8, 0x9e,
0xea, 0xbf, 0x8a, 0xd2, 0x40, 0xc7, 0x38, 0xb5,
0xa3, 0xf7, 0xf2, 0xce, 0xf9, 0x61, 0x15, 0xa1,
0xe0, 0xae, 0x5d, 0xa4, 0x9b, 0x34, 0x1a, 0x55,
0xad, 0x93, 0x32, 0x30, 0xf5, 0x8c, 0xb1, 0xe3,
0x1d, 0xf6, 0xe2, 0x2e, 0x82, 0x66, 0xca, 0x60,
0xc0, 0x29, 0x23, 0xab, 0x0d, 0x53, 0x4e, 0x6f,
0xd5, 0xdb, 0x37, 0x45, 0xde, 0xfd, 0x8e, 0x2f,
0x03, 0xff, 0x6a, 0x72, 0x6d, 0x6c, 0x5b, 0x51,
0x8d, 0x1b, 0xaf, 0x92, 0xbb, 0xdd, 0xbc, 0x7f,
0x11, 0xd9, 0x5c, 0x41, 0x1f, 0x10, 0x5a, 0xd8,
0x0a, 0xc1, 0x31, 0x88, 0xa5, 0xcd, 0x7b, 0xbd,
0x2d, 0x74, 0xd0, 0x12, 0xb8, 0xe5, 0xb4, 0xb0,
0x89, 0x69, 0x97, 0x4a, 0x0c, 0x96, 0x77, 0x7e,
0x65, 0xb9, 0xf1, 0x09, 0xc5, 0x6e, 0xc6, 0x84,
0x18, 0xf0, 0x7d, 0xec, 0x3a, 0xdc, 0x4d, 0x20,
0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48,
};
void HELPER(crypto_sm4e)(void *vd, void *vn)
{
uint64_t *rd = vd;
uint64_t *rn = vn;
union CRYPTO_STATE d;
union CRYPTO_STATE n;
uint32_t t, i;
d.l[0] = rd[0];
d.l[1] = rd[1];
n.l[0] = rn[0];
n.l[1] = rn[1];
for (i = 0; i < 4; i++) {
t = CR_ST_WORD(d, (i + 1) % 4) ^
CR_ST_WORD(d, (i + 2) % 4) ^
CR_ST_WORD(d, (i + 3) % 4) ^
CR_ST_WORD(n, i);
t = sm4_sbox[t & 0xff] |
sm4_sbox[(t >> 8) & 0xff] << 8 |
sm4_sbox[(t >> 16) & 0xff] << 16 |
sm4_sbox[(t >> 24) & 0xff] << 24;
CR_ST_WORD(d, i) ^= t ^ rol32(t, 2) ^ rol32(t, 10) ^ rol32(t, 18) ^
rol32(t, 24);
}
rd[0] = d.l[0];
rd[1] = d.l[1];
}
void HELPER(crypto_sm4ekey)(void *vd, void *vn, void* vm)
{
uint64_t *rd = vd;
uint64_t *rn = vn;
uint64_t *rm = vm;
union CRYPTO_STATE d;
union CRYPTO_STATE n;
union CRYPTO_STATE m;
uint32_t t, i;
n.l[0] = rn[0];
n.l[1] = rn[1];
m.l[0] = rm[0];
m.l[1] = rm[1];
d = n;
for (i = 0; i < 4; i++) {
t = CR_ST_WORD(d, (i + 1) % 4) ^
CR_ST_WORD(d, (i + 2) % 4) ^
CR_ST_WORD(d, (i + 3) % 4) ^
CR_ST_WORD(m, i);
t = sm4_sbox[t & 0xff] |
sm4_sbox[(t >> 8) & 0xff] << 8 |
sm4_sbox[(t >> 16) & 0xff] << 16 |
sm4_sbox[(t >> 24) & 0xff] << 24;
CR_ST_WORD(d, i) ^= t ^ rol32(t, 13) ^ rol32(t, 23);
}
rd[0] = d.l[0];
rd[1] = d.l[1];
}

View File

@ -545,6 +545,9 @@ DEF_HELPER_FLAGS_5(crypto_sm3tt, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32, i32)
DEF_HELPER_FLAGS_3(crypto_sm3partw1, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
DEF_HELPER_FLAGS_3(crypto_sm3partw2, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
DEF_HELPER_FLAGS_2(crypto_sm4e, TCG_CALL_NO_RWG, void, ptr, ptr)
DEF_HELPER_FLAGS_3(crypto_sm4ekey, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
DEF_HELPER_FLAGS_3(crc32_arm, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)
DEF_HELPER_FLAGS_3(crc32c, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)
DEF_HELPER_2(dc_zva, void, env, i64)

View File

@ -11788,6 +11788,10 @@ static void disas_crypto_three_reg_sha512(DisasContext *s, uint32_t insn)
feature = ARM_FEATURE_V8_SM3;
genfn = gen_helper_crypto_sm3partw2;
break;
case 2: /* SM4EKEY */
feature = ARM_FEATURE_V8_SM4;
genfn = gen_helper_crypto_sm4ekey;
break;
default:
unallocated_encoding(s);
return;
@ -11862,6 +11866,10 @@ static void disas_crypto_two_reg_sha512(DisasContext *s, uint32_t insn)
feature = ARM_FEATURE_V8_SHA512;
genfn = gen_helper_crypto_sha512su0;
break;
case 1: /* SM4E */
feature = ARM_FEATURE_V8_SM4;
genfn = gen_helper_crypto_sm4e;
break;
default:
unallocated_encoding(s);
return;

View File

@ -1604,6 +1604,8 @@
#define helper_crypto_sm3partw1 helper_crypto_sm3partw1_x86_64
#define helper_crypto_sm3partw2 helper_crypto_sm3partw2_x86_64
#define helper_crypto_sm3tt helper_crypto_sm3tt_x86_64
#define helper_crypto_sm4e helper_crypto_sm4e_x86_64
#define helper_crypto_sm4ekey helper_crypto_sm4ekey_x86_64
#define helper_dc_zva helper_dc_zva_x86_64
#define helper_div_i32 helper_div_i32_x86_64
#define helper_div_i64 helper_div_i64_x86_64