Messaging Layer Security (MLS) in GoMessaging Layer Security (MLS) was initially proposed in 2016 and integrates end-to-end encrypting of messages. It has been defined by the IETF MLS working group, and integrates message confidentiality, message integrity and authentication, membership authentication, asynchronicity, forward secrecy, post-compromise security, and scalability. A final draft from the IETF for MLS was published on 29 Mar 2023 [here]. In this case, we will use PBKDF2 to generate an encryption key. We can use X25519_AES128GCM_SHA256_Ed25519, and which integrates 128-bit (32 bytes) AES with GCM mode. Other modes are: P256_AES128GCM_SHA256_P256, X25519_CHACHA20POLY1305_SHA256_Ed25519 and P521_AES256GCM_SHA512_P521. |
Outline
The use of SSL/TLS fixed the problem of transmitting data packets without encryption, and in not checking the trustworthiness of the servers that we connected to. But, this is closing the door after the horse has bolted. Thus the way we do our authentication for security tunnels is also often flawed, such as:
- Supporting many legacy cryptography methods (such as the Diffie-Hellman key exchange method, the SHA-1 hashing method and 3DES symmetric key encryption).
- Adding large RSA signatures and which authenticate just one side of the communication.
- Easy to install a proxy on a machine and listen to the network traffic.
- Easy to break the communications channel (such as with a WAF — Web Application Firewall) and inspect the traffic.
The best way to secure data is to encrypt it at its source. We typically define this as end-to-end encryption. And one of the newest open standards — Messaging Layer Security (MLS) — has just been published by the IETF [here]:
Key properties of MLS
The focus of MLS is to setup users which integrate into groups, and includes the key properties of:
- Message Confidentiality. This is where messages can only be seen within a given group.
- Message Integrity and Authentication. Each message is tagged to ensure both integrity of the message and for a check on the sender of the message.
- Membership Authentication. This is where each user can determine the other users in the group.
- Asynchronicity. With this, we can create keys without the need for users to be online.
- Forward secrecy. Any compromise of a single key will not cause the previous keys to be breached.
- Post-compromise security. A compromise of a node will not compromise future messages from a given group.
- Scalability. This supports scaling of group sizes without affecting performance too much.
Messaging Layer Security (MLS)
Messaging Layer Security (MLS) was initially proposed in 2016 and integrates end-to-end encrypting of messages. It has been defined by the IETF MLS working group, which includes authors from Cisco, Google, Mozilla, Meta, Phoenix R&D, and the University of Oxford. Overall, it uses best-in-practice encryption methods to define the cryptographic suite. For the message privacy, we need symmetric key encryption, such as with AES and ChaCha20. In order to generate the symmetric key, we need a key exchange method (such as ECDH using P256 or P521 or X25519 using Curve 25519). Finally, we need a digital signature method to sign messages, such as Ed25519 (which uses Curve 25519), P256 (which uses ECDSA) or P521 (which also uses ECDSA).
The cryptographic suites supported by MLS include:
- X25519_AES128GCM_SHA256_Ed25519. This integrates 128-bit (32 bytes) AES with GCM mode, and uses X25519 for key exchange, SHA256 for hashing and Ed25519 for digital signatures.
- P256_AES128GCM_SHA256_P256. This integrates 128-bit (32 bytes) AES with GCM mode, and uses P256 (secp256r1) for key exchange, SHA256 for hashing and ECDSA (using P256) for digital signatures.
- X25519_CHACHA20POLY1305_SHA256_Ed25519. This integrates 128-bit (32 bytes) ChaCha20 with Poly1305 for authentication, and uses X25519 for key exchange, SHA256 for hashing and Ed25519 for digital signatures.
- P521_AES256GCM_SHA512_P521. This integrates 256-bit (64 bytes) AES with GCM mode, and uses P521 for key exchange, SHA256 for hashing and ECDSA (with P521) for digital signatures.
Coding
In this case, we will use PBKDF2 to generate an encryption key. We can use X25519_AES128GCM_SHA256_Ed25519, and which integrates 128-bit (32 bytes) AES with GCM mode. In the following, we will use a salt value of all zeros for the encryption key generation, a nonce value of all zeros, and additional data of "00".
To install the required Golang library, we need:
go get github.com/cisco/go-mls
The following is some sample code:
package main import ( "fmt" "encoding/hex" mls "github.com/cisco/go-mls" "golang.org/x/crypto/pbkdf2" "crypto/sha256" "os" ) func unhex(h string) []byte { b, err := hex.DecodeString(h) if err != nil { panic(err) } return b } func main() { suite := mls.X25519_AES128GCM_SHA256_Ed25519 var key, nonce, aad, pt, ct []byte msg:="hello" passwd:="Test" mode:="0" argCount := len(os.Args[1:]) if (argCount>0) {msg= string(os.Args[1])} if (argCount>1) {passwd= string(os.Args[2])} if (argCount>2) {mode= string(os.Args[3])} salt:=[]byte("000000000000") nonce =unhex("000000000000000000000000") key = pbkdf2.Key([]byte(passwd), salt, 10000, 16, sha256.New) if (mode=="1") { suite = mls.P256_AES128GCM_SHA256_P256 } if (mode=="2") { suite = mls.X25519_CHACHA20POLY1305_SHA256_Ed25519 key = pbkdf2.Key([]byte(passwd), salt, 10000, 32, sha256.New) } if (mode=="3") { suite = mls.P521_AES256GCM_SHA512_P521 key = pbkdf2.Key([]byte(passwd), salt, 10000, 32, sha256.New) } pt=[]byte(msg) aad = unhex("00") aead, _ := suite.NewAEAD(key) ct = aead.Seal(nil, nonce, pt, aad) decrypted, _ := aead.Open(nil, nonce, ct, aad) fmt.Printf("Message:\t%s\n", pt) fmt.Printf("Password:\t%s\n", passwd) fmt.Printf("Type:\t\t%s\n\n", suite.String()) fmt.Printf("Key:\t\t%x\n\n", key) fmt.Printf("Encrypted:\t%x\n", ct) fmt.Printf("Decrypted:\t%s\n", decrypted) }
And a sample run:
Message: Testing 123 Password: qwerty Encrypted: 238f1e722c58e9a680b4b6ed4c80cd08f5be57b03fa39cfea72088 Decrypted: Testing 123