From 5bafb3df59e0a936a9b3efba711d526f724bb404 Mon Sep 17 00:00:00 2001 From: Sun Yimin Date: Wed, 16 Feb 2022 16:03:09 +0800 Subject: [PATCH] =?UTF-8?q?Updated=20Armv8.2=20SM3=E5=92=8CSM4=20(markdown?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Armv8.2-SM3和SM4.md | 62 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/Armv8.2-SM3和SM4.md b/Armv8.2-SM3和SM4.md index 5bc7222..e912a1c 100644 --- a/Armv8.2-SM3和SM4.md +++ b/Armv8.2-SM3和SM4.md @@ -41,6 +41,68 @@ AESE指令相当于: ok github.com/emmansun/gmsm/sm4 5.334s ``` +## SM4 with SM4E & SM4EKEY +[SM4EKEY](https://developer.arm.com/documentation/ddi0596/2021-12/SIMD-FP-Instructions/SM4EKEY--SM4-Key-?lang=en) +[SM4E](https://developer.arm.com/documentation/ddi0596/2021-12/SIMD-FP-Instructions/SM4E--SM4-Encode-?lang=en) +目前golang还没有支持SM4E/SM4EKEY指令,不过我们可以根据[不支持的操作码](https://go.dev/doc/asm#unsupported_opcodes)来处理: +1. Clone codes from https://github.com/golang/arch +2. 修改arm64asm/tables.go: 增加SM4E/SM4EKEY常量;同时加入opstr;加入指令到instFormats。 +![image](https://user-images.githubusercontent.com/7235232/154217159-6111ed63-41e8-42df-8aef-c8fb144e68c4.png) +``` + // SM4E .4S, .4S + {0xfffffc00, 0xcec08400, SM4E, instArgs{arg_Vd_arrangement_4S, arg_Vn_arrangement_4S}, nil}, + // SM4EKEY .4S, .4S, .4S + {0xffe0fc00, 0xce60c800, SM4EKEY, instArgs{arg_Vd_arrangement_4S, arg_Vn_arrangement_4S, arg_Vm_arrangement_4S}, nil}, +``` +2. 修改arm64asm/plan9x.go,noSuffixOpSet里加上SM4E和SM4EKEY,这个是可选的,加了的话,plan9x的指令就不会出现V前缀。 +3. 写测试,testDecodeLine()方法是从decode_test.go的testDecode()方法中抽出来的。看了那个Decode()方法就能编码出那些32位的code了。 +``` + +func TestDecodeSM4Codes(t *testing.T) { + //gnu syntax, load 16 bytes plaintext to v8 (need to reverse byte order first), 32 round keys to v0-v7, the final result should be reverse byte order again + testDecodeLine(t, "gnu", "0884c0ce| sm4e v8.4s, v0.4s") + testDecodeLine(t, "gnu", "2884c0ce| sm4e v8.4s, v1.4s") + testDecodeLine(t, "gnu", "4884c0ce| sm4e v8.4s, v2.4s") + testDecodeLine(t, "gnu", "6884c0ce| sm4e v8.4s, v3.4s") + testDecodeLine(t, "gnu", "8884c0ce| sm4e v8.4s, v4.4s") + testDecodeLine(t, "gnu", "a884c0ce| sm4e v8.4s, v5.4s") + testDecodeLine(t, "gnu", "c884c0ce| sm4e v8.4s, v6.4s") + testDecodeLine(t, "gnu", "e884c0ce| sm4e v8.4s, v7.4s") + //plan9 syntax, load 16 bytes plaintext to v8 (need to reverse byte order first), 32 round keys to v0-v7, the final result should be reverse byte order again + testDecodeLine(t, "plan9", "0884c0ce| SM4E V0.S4, V8.S4") + testDecodeLine(t, "plan9", "2884c0ce| SM4E V1.S4, V8.S4") + testDecodeLine(t, "plan9", "4884c0ce| SM4E V2.S4, V8.S4") + testDecodeLine(t, "plan9", "6884c0ce| SM4E V3.S4, V8.S4") + testDecodeLine(t, "plan9", "8884c0ce| SM4E V4.S4, V8.S4") + testDecodeLine(t, "plan9", "a884c0ce| SM4E V5.S4, V8.S4") + testDecodeLine(t, "plan9", "c884c0ce| SM4E V6.S4, V8.S4") + testDecodeLine(t, "plan9", "e884c0ce| SM4E V7.S4, V8.S4") + //gnu syntax, load 32 ck to v0-v7, root key (reverse byte order first) xor fk to v8, the result round keys will be in v9, need to move v9 to v8 from second invocation of sm4ekey + testDecodeLine(t, "gnu", "09c960ce| sm4ekey v9.4s, v8.4s, v0.4s") + testDecodeLine(t, "gnu", "09c961ce| sm4ekey v9.4s, v8.4s, v1.4s") + testDecodeLine(t, "gnu", "09c962ce| sm4ekey v9.4s, v8.4s, v2.4s") + testDecodeLine(t, "gnu", "09c963ce| sm4ekey v9.4s, v8.4s, v3.4s") + testDecodeLine(t, "gnu", "09c964ce| sm4ekey v9.4s, v8.4s, v4.4s") + testDecodeLine(t, "gnu", "09c965ce| sm4ekey v9.4s, v8.4s, v5.4s") + testDecodeLine(t, "gnu", "09c966ce| sm4ekey v9.4s, v8.4s, v6.4s") + testDecodeLine(t, "gnu", "09c967ce| sm4ekey v9.4s, v8.4s, v7.4s") + //gnu syntax, load 32 ck to v0-v7, root key (reverse byte order first) xor fk to v8, the result round keys will be in v9 (1,3,5,7) and v8 (2,4,6,8),避免寄存器copy。 + testDecodeLine(t, "gnu", "09c960ce| sm4ekey v9.4s, v8.4s, v0.4s") + testDecodeLine(t, "gnu", "28c961ce| sm4ekey v8.4s, v9.4s, v1.4s") + testDecodeLine(t, "gnu", "09c962ce| sm4ekey v9.4s, v8.4s, v2.4s") + testDecodeLine(t, "gnu", "28c963ce| sm4ekey v8.4s, v9.4s, v3.4s") + testDecodeLine(t, "gnu", "09c964ce| sm4ekey v9.4s, v8.4s, v4.4s") + testDecodeLine(t, "gnu", "28c965ce| sm4ekey v8.4s, v9.4s, v5.4s") + testDecodeLine(t, "gnu", "09c966ce| sm4ekey v9.4s, v8.4s, v6.4s") + testDecodeLine(t, "gnu", "28c967ce| sm4ekey v8.4s, v9.4s, v7.4s") +} +``` +4.然后,你就可以在golang的arm64的汇编中使用那些32位的codes了。 +``` +WORD $0x0884c0ce // SM4E V0.S4, V8.S4 +``` +可惜没有环境!!! + ## Reference SM3和SM4 CPU指令实现,找不到相关CPU环境,mark先。 1. [Summary of A64 cryptographic instructions](https://developer.arm.com/documentation/100076/0100/a64-instruction-set-reference/a64-cryptographic-algorithms/a64-cryptographic-instructions?lang=en)