China and the SM Ciphers: Here’s SM4

And, so, NIST has defined AES as the standard for symmetric key encryption. But, NIST was pinpointed in possibly pushing a cipher with an…

Photo by Hans-Peter Gauster on Unsplash

China and the SM Ciphers: Here’s SM4

And, so, NIST has defined AES as the standard for symmetric key encryption. But, NIST was pinpointed in possibly pushing a cipher with an NSA backdoor. For companies in China, the ShāngMì (SM) series of ciphers provide one alternative for TLS 1.3 integration and Wireless authentication. SM2 defines authentication, SM3 defines a hashing function, and SM4 for encryption. SM4 was developed by Lü Shuwang in 2007 and became a national standard (GB/T 32907–2016) in 2016. It has also been defined in RFC 8998 [here]:

With the SM4 cipher, we have a block size of 128 bits and a 128-bit encryption key. Each block of data has 32 rounds of processing. Overall, we can add a salt value of 128 bits in an IV (Initialisation Vector).

We can code with [here]:

import os
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.primitives import padding
import sys

message="Hello"

keysize=16
iv = os.urandom(16)
mode=0

if (len(sys.argv)>1):
message=str(sys.argv[1])
if (len(sys.argv)>2):
mode=int(sys.argv[2])

key = os.urandom(keysize)

padder = padding.PKCS7(128).padder()

unpadder = padding.PKCS7(128).unpadder()

cipher=None

if (mode==0):
cipher = Cipher(algorithms.SM4(key), modes.CBC(iv))
if (mode==1):
cipher = Cipher(algorithms.SM4(key), modes.OFB(iv))
if (mode==2):
cipher = Cipher(algorithms.SM4(key), modes.CFB(iv))
if (mode==3):
cipher = Cipher(algorithms.SM4(key), modes.CTR(iv))
if (mode==4):
cipher = Cipher(algorithms.SM4(key), modes.ECB())

encryptor = cipher.encryptor()


str=padder.update(message.encode())+padder.finalize()

ciphertext = encryptor.update(str ) + encryptor.finalize()

# Now decrypt

decryptor = cipher.decryptor()


rtn=unpadder.update(decryptor.update(ciphertext) + decryptor.finalize())+unpadder.finalize()


print("Type:\t\t\t",cipher.algorithm.name)
print("Mode:\t\t\t",cipher.mode.name)
print("Message:\t\t",message)
print("Message with padding:\t",str)
print("\nKey:\t\t\t",key.hex())
if (mode!=4): print("IV:\t\t\t",iv.hex())
print("\nCipher:\t\t\t",ciphertext.hex())
print("Decrypt:\t\t",rtn.decode())

and a test run of [here]:

Type:    SM4
Mode: CBC
Message: Hello
Message with padding: b'Hello\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b'

Key: ff010929f29f618ea5181a6a2e9de7a0
IV: 56f8a40da11cd93a67172311470879c3

Cipher: 292994cf3bf587e2b9f020a6c94026c1
Decrypt: Hello

SM4 is also a core part of OpenSSL 3.x:

https://asecuritysite.com/openssl/openssl3

Conclusions

While mandatory in China, SM4 provides an alternative to AES and ChaCha20.