sm4.go 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. /*
  2. Copyright Suzhou Tongji Fintech Research Institute 2017 All Rights Reserved.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package sm4
  14. import (
  15. "crypto/cipher"
  16. "crypto/rand"
  17. "crypto/x509"
  18. "encoding/pem"
  19. "errors"
  20. "io/ioutil"
  21. "os"
  22. "strconv"
  23. )
  24. const BlockSize = 16
  25. type SM4Key []byte
  26. type KeySizeError int
  27. // Cipher is an instance of SM4 encryption.
  28. type Sm4Cipher struct {
  29. subkeys []uint32
  30. block1 []uint32
  31. block2 []byte
  32. }
  33. // sm4密钥参量
  34. var fk = [4]uint32{
  35. 0xa3b1bac6, 0x56aa3350, 0x677d9197, 0xb27022dc,
  36. }
  37. // sm4密钥参量
  38. var ck = [32]uint32{
  39. 0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269,
  40. 0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9,
  41. 0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249,
  42. 0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9,
  43. 0xc0c7ced5, 0xdce3eaf1, 0xf8ff060d, 0x141b2229,
  44. 0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299,
  45. 0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209,
  46. 0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279,
  47. }
  48. // sm4密钥参量
  49. var sbox = [256]uint8{
  50. 0xd6, 0x90, 0xe9, 0xfe, 0xcc, 0xe1, 0x3d, 0xb7, 0x16, 0xb6, 0x14, 0xc2, 0x28, 0xfb, 0x2c, 0x05,
  51. 0x2b, 0x67, 0x9a, 0x76, 0x2a, 0xbe, 0x04, 0xc3, 0xaa, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99,
  52. 0x9c, 0x42, 0x50, 0xf4, 0x91, 0xef, 0x98, 0x7a, 0x33, 0x54, 0x0b, 0x43, 0xed, 0xcf, 0xac, 0x62,
  53. 0xe4, 0xb3, 0x1c, 0xa9, 0xc9, 0x08, 0xe8, 0x95, 0x80, 0xdf, 0x94, 0xfa, 0x75, 0x8f, 0x3f, 0xa6,
  54. 0x47, 0x07, 0xa7, 0xfc, 0xf3, 0x73, 0x17, 0xba, 0x83, 0x59, 0x3c, 0x19, 0xe6, 0x85, 0x4f, 0xa8,
  55. 0x68, 0x6b, 0x81, 0xb2, 0x71, 0x64, 0xda, 0x8b, 0xf8, 0xeb, 0x0f, 0x4b, 0x70, 0x56, 0x9d, 0x35,
  56. 0x1e, 0x24, 0x0e, 0x5e, 0x63, 0x58, 0xd1, 0xa2, 0x25, 0x22, 0x7c, 0x3b, 0x01, 0x21, 0x78, 0x87,
  57. 0xd4, 0x00, 0x46, 0x57, 0x9f, 0xd3, 0x27, 0x52, 0x4c, 0x36, 0x02, 0xe7, 0xa0, 0xc4, 0xc8, 0x9e,
  58. 0xea, 0xbf, 0x8a, 0xd2, 0x40, 0xc7, 0x38, 0xb5, 0xa3, 0xf7, 0xf2, 0xce, 0xf9, 0x61, 0x15, 0xa1,
  59. 0xe0, 0xae, 0x5d, 0xa4, 0x9b, 0x34, 0x1a, 0x55, 0xad, 0x93, 0x32, 0x30, 0xf5, 0x8c, 0xb1, 0xe3,
  60. 0x1d, 0xf6, 0xe2, 0x2e, 0x82, 0x66, 0xca, 0x60, 0xc0, 0x29, 0x23, 0xab, 0x0d, 0x53, 0x4e, 0x6f,
  61. 0xd5, 0xdb, 0x37, 0x45, 0xde, 0xfd, 0x8e, 0x2f, 0x03, 0xff, 0x6a, 0x72, 0x6d, 0x6c, 0x5b, 0x51,
  62. 0x8d, 0x1b, 0xaf, 0x92, 0xbb, 0xdd, 0xbc, 0x7f, 0x11, 0xd9, 0x5c, 0x41, 0x1f, 0x10, 0x5a, 0xd8,
  63. 0x0a, 0xc1, 0x31, 0x88, 0xa5, 0xcd, 0x7b, 0xbd, 0x2d, 0x74, 0xd0, 0x12, 0xb8, 0xe5, 0xb4, 0xb0,
  64. 0x89, 0x69, 0x97, 0x4a, 0x0c, 0x96, 0x77, 0x7e, 0x65, 0xb9, 0xf1, 0x09, 0xc5, 0x6e, 0xc6, 0x84,
  65. 0x18, 0xf0, 0x7d, 0xec, 0x3a, 0xdc, 0x4d, 0x20, 0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48,
  66. }
  67. func rl(x uint32, i uint8) uint32 { return (x << (i % 32)) | (x >> (32 - (i % 32))) }
  68. func l0(b uint32) uint32 { return b ^ rl(b, 13) ^ rl(b, 23) }
  69. func l1(b uint32) uint32 { return b ^ rl(b, 2) ^ rl(b, 10) ^ rl(b, 18) ^ rl(b, 24) }
  70. func feistel0(x0, x1, x2, x3, rk uint32) uint32 { return x0 ^ l0(p(x1^x2^x3^rk)) }
  71. func feistel1(x0, x1, x2, x3, rk uint32) uint32 { return x0 ^ l1(p(x1^x2^x3^rk)) }
  72. //非线性变换τ(.)
  73. func p(a uint32) uint32 {
  74. return (uint32(sbox[a>>24]) << 24) ^ (uint32(sbox[(a>>16)&0xff]) << 16) ^ (uint32(sbox[(a>>8)&0xff]) << 8) ^ uint32(sbox[(a)&0xff])
  75. }
  76. /*
  77. func permuteInitialBlock(block []byte) []uint32 {
  78. b := make([]uint32, 4, 4)
  79. for i := 0; i < 4; i++ {
  80. b[i] = (uint32(block[i*4]) << 24) | (uint32(block[i*4+1]) << 16) |
  81. (uint32(block[i*4+2]) << 8) | (uint32(block[i*4+3]))
  82. }
  83. return b
  84. }
  85. func permuteFinalBlock(block []uint32) []byte {
  86. b := make([]byte, 16, 16)
  87. for i := 0; i < 4; i++ {
  88. b[i*4] = uint8(block[i] >> 24)
  89. b[i*4+1] = uint8(block[i] >> 16)
  90. b[i*4+2] = uint8(block[i] >> 8)
  91. b[i*4+3] = uint8(block[i])
  92. }
  93. return b
  94. }
  95. func cryptBlock(subkeys []uint32, dst, src []byte, decrypt bool) {
  96. var tm uint32
  97. b := permuteInitialBlock(src)
  98. for i := 0; i < 32; i++ {
  99. if decrypt {
  100. tm = feistel1(b[0], b[1], b[2], b[3], subkeys[31-i])
  101. } else {
  102. tm = feistel1(b[0], b[1], b[2], b[3], subkeys[i])
  103. }
  104. b[0], b[1], b[2], b[3] = b[1], b[2], b[3], tm
  105. }
  106. b[0], b[1], b[2], b[3] = b[3], b[2], b[1], b[0]
  107. copy(dst, permuteFinalBlock(b))
  108. }
  109. */
  110. func permuteInitialBlock(b []uint32, block []byte) {
  111. for i := 0; i < 4; i++ {
  112. b[i] = (uint32(block[i*4]) << 24) | (uint32(block[i*4+1]) << 16) |
  113. (uint32(block[i*4+2]) << 8) | (uint32(block[i*4+3]))
  114. }
  115. }
  116. func permuteFinalBlock(b []byte, block []uint32) {
  117. for i := 0; i < 4; i++ {
  118. b[i*4] = uint8(block[i] >> 24)
  119. b[i*4+1] = uint8(block[i] >> 16)
  120. b[i*4+2] = uint8(block[i] >> 8)
  121. b[i*4+3] = uint8(block[i])
  122. }
  123. }
  124. func cryptBlock(subkeys []uint32, b []uint32, r []byte, dst, src []byte, decrypt bool) {
  125. var tm uint32
  126. permuteInitialBlock(b, src)
  127. for i := 0; i < 32; i++ {
  128. if decrypt {
  129. tm = b[0] ^ l1(p(b[1]^b[2]^b[3]^subkeys[31 - i]))
  130. // tm = feistel1(b[0], b[1], b[2], b[3], subkeys[31-i])
  131. } else {
  132. tm = b[0] ^ l1(p(b[1]^b[2]^b[3]^subkeys[i]))
  133. // tm = feistel1(b[0], b[1], b[2], b[3], subkeys[i])
  134. }
  135. b[0], b[1], b[2], b[3] = b[1], b[2], b[3], tm
  136. }
  137. b[0], b[1], b[2], b[3] = b[3], b[2], b[1], b[0]
  138. permuteFinalBlock(r, b)
  139. copy(dst, r)
  140. }
  141. func generateSubKeys(key []byte) []uint32 {
  142. subkeys := make([]uint32, 32)
  143. b := make([]uint32, 4)
  144. // b := permuteInitialBlock(key)
  145. permuteInitialBlock(b, key)
  146. b[0] ^= fk[0]
  147. b[1] ^= fk[1]
  148. b[2] ^= fk[2]
  149. b[3] ^= fk[3]
  150. for i := 0; i < 32; i++ {
  151. subkeys[i] = feistel0(b[0], b[1], b[2], b[3], ck[i])
  152. b[0], b[1], b[2], b[3] = b[1], b[2], b[3], subkeys[i]
  153. }
  154. return subkeys
  155. }
  156. func EncryptBlock(key SM4Key, dst, src []byte) {
  157. subkeys := generateSubKeys(key)
  158. cryptBlock(subkeys, make([]uint32, 4), make([]byte, 16), dst, src, false)
  159. }
  160. func DecryptBlock(key SM4Key, dst, src []byte) {
  161. subkeys := generateSubKeys(key)
  162. cryptBlock(subkeys, make([]uint32, 4), make([]byte, 16), dst, src, true)
  163. }
  164. func ReadKeyFromMem(data []byte, pwd []byte) (SM4Key, error) {
  165. block, _ := pem.Decode(data)
  166. if x509.IsEncryptedPEMBlock(block) {
  167. if block.Type != "SM4 ENCRYPTED KEY" {
  168. return nil, errors.New("SM4: unknown type")
  169. }
  170. if pwd == nil {
  171. return nil, errors.New("SM4: need passwd")
  172. }
  173. data, err := x509.DecryptPEMBlock(block, pwd)
  174. if err != nil {
  175. return nil, err
  176. }
  177. return data, nil
  178. }
  179. if block.Type != "SM4 KEY" {
  180. return nil, errors.New("SM4: unknown type")
  181. }
  182. return block.Bytes, nil
  183. }
  184. func ReadKeyFromPem(FileName string, pwd []byte) (SM4Key, error) {
  185. data, err := ioutil.ReadFile(FileName)
  186. if err != nil {
  187. return nil, err
  188. }
  189. return ReadKeyFromMem(data, pwd)
  190. }
  191. func WriteKeytoMem(key SM4Key, pwd []byte) ([]byte, error) {
  192. if pwd != nil {
  193. block, err := x509.EncryptPEMBlock(rand.Reader,
  194. "SM4 ENCRYPTED KEY", key, pwd, x509.PEMCipherAES256)
  195. if err != nil {
  196. return nil, err
  197. }
  198. return pem.EncodeToMemory(block), nil
  199. } else {
  200. block := &pem.Block{
  201. Type: "SM4 KEY",
  202. Bytes: key,
  203. }
  204. return pem.EncodeToMemory(block), nil
  205. }
  206. }
  207. func WriteKeyToPem(FileName string, key SM4Key, pwd []byte) (bool, error) {
  208. var block *pem.Block
  209. if pwd != nil {
  210. var err error
  211. block, err = x509.EncryptPEMBlock(rand.Reader,
  212. "SM4 ENCRYPTED KEY", key, pwd, x509.PEMCipherAES256)
  213. if err != nil {
  214. return false, err
  215. }
  216. } else {
  217. block = &pem.Block{
  218. Type: "SM4 KEY",
  219. Bytes: key,
  220. }
  221. }
  222. file, err := os.Create(FileName)
  223. if err != nil {
  224. return false, err
  225. }
  226. defer file.Close()
  227. err = pem.Encode(file, block)
  228. if err != nil {
  229. return false, nil
  230. }
  231. return true, nil
  232. }
  233. func (k KeySizeError) Error() string {
  234. return "SM4: invalid key size " + strconv.Itoa(int(k))
  235. }
  236. // NewCipher creates and returns a new cipher.Block.
  237. func NewCipher(key []byte) (cipher.Block, error) {
  238. if len(key) != BlockSize {
  239. return nil, KeySizeError(len(key))
  240. }
  241. c := new(Sm4Cipher)
  242. c.subkeys = generateSubKeys(key)
  243. c.block1 = make([]uint32, 4)
  244. c.block2 = make([]byte, 16)
  245. return c, nil
  246. }
  247. func (c *Sm4Cipher) BlockSize() int {
  248. return BlockSize
  249. }
  250. func (c *Sm4Cipher) Encrypt(dst, src []byte) {
  251. cryptBlock(c.subkeys, c.block1, c.block2, dst, src, false)
  252. }
  253. func (c *Sm4Cipher) Decrypt(dst, src []byte) {
  254. cryptBlock(c.subkeys, c.block1, c.block2, dst, src, true)
  255. }