Repository: threefoldtech/zos
Pull request #998 (2020-10-14 09:33:43)

do hash the shared secret generated to decrypt workloads sensitive information
Extract from
https://en.wikipedia.org/wiki/Elliptic-curve_Diffie%E2%80%93Hellman#Key_establishment_protocol:
> While the shared secret may be used directly as a key, it can be desirable to hash the secret to remove weak bits due to the Diffie–Hellman exchange.


Patch:
diff --git a/pkg/crypto/encryption.go b/pkg/crypto/encryption.go
index 132344d4..1e9e6e30 100644
--- a/pkg/crypto/encryption.go
+++ b/pkg/crypto/encryption.go
@@ -7,6 +7,7 @@ import (
 
 	"github.com/agl/ed25519/extra25519"
 	box "github.com/whs/nacl-sealed-box"
+	"golang.org/x/crypto/blake2b"
 	"golang.org/x/crypto/curve25519"
 	"golang.org/x/crypto/nacl/secretbox"
 )
@@ -48,34 +49,30 @@ func PublicKeyToCurve25519(pk ed25519.PublicKey) [32]byte {
 // DecryptECDH decrypt aes encrypted msg using a shared key derived from sk and pk using Elliptic curve Diffie Helman algorithm
 func DecryptECDH(msg []byte, sk ed25519.PrivateKey, pk ed25519.PublicKey) ([]byte, error) {
 
-	sharedSecretBytes, err := sharedSecret(sk, pk)
+	key, err := sharedSecret(sk, pk)
 	if err != nil {
 		return nil, err
 	}
-	var key [32]byte
-	copy(key[:], sharedSecretBytes)
 
 	var nonce [24]byte
 	copy(nonce[:], msg[:24])
 
-	descrypted, ok := secretbox.Open(nil, msg[24:], &nonce, &key)
+	decrypted, ok := secretbox.Open(nil, msg[24:], &nonce, &key)
 	if !ok {
 		return nil, fmt.Errorf("decryption error")
 	}
 
-	return descrypted, nil
+	return decrypted, nil
 }
 
 // EncryptECDH aes encrypt msg using a shared key derived from sk and pk using Elliptic curve Diffie Helman algorithm
 // the nonce if prepended to the encrypted message
 func EncryptECDH(msg []byte, sk ed25519.PrivateKey, pk ed25519.PublicKey) ([]byte, error) {
 
-	sharedSecretBytes, err := sharedSecret(sk, pk)
+	key, err := sharedSecret(sk, pk)
 	if err != nil {
 		return nil, err
 	}
-	var key [32]byte
-	copy(key[:], sharedSecretBytes)
 
 	var nonce [24]byte
 	if _, err = rand.Read(nonce[:]); err != nil {
@@ -87,13 +84,14 @@ func EncryptECDH(msg []byte, sk ed25519.PrivateKey, pk ed25519.PublicKey) ([]byt
 
 }
 
-func sharedSecret(sk ed25519.PrivateKey, pk ed25519.PublicKey) ([]byte, error) {
+func sharedSecret(sk ed25519.PrivateKey, pk ed25519.PublicKey) ([32]byte, error) {
 	private := PrivateKeyToCurve25519(sk)
 	public := PublicKeyToCurve25519(pk)
 
 	shareSecret, err := curve25519.X25519(private[:], public[:])
 	if err != nil {
-		return nil, err
+		return [32]byte{}, err
 	}
-	return shareSecret, nil
+
+	return blake2b.Sum256(shareSecret), nil
 }


Test patch:
diff --git a/pkg/crypto/crypto_test.go b/pkg/crypto/crypto_test.go
index fc8ee0d3..c6ac7c8d 100644
--- a/pkg/crypto/crypto_test.go
+++ b/pkg/crypto/crypto_test.go
@@ -111,18 +111,21 @@ func TestECDHPyNACLCompatibility(t *testing.T) {
 	// import nacl.encoding
 	// from nacl.secret import SecretBox
 	// from nacl.bindings import crypto_scalarmult
+	// from hashlib import blake2b
 	// alice_private = nacl.public.PrivateKey.from_seed(b"11111111111111111111111111111111")
 	// bob_private = nacl.public.PrivateKey.from_seed(b"22222222222222222222222222222222")
 	// shared_secret = crypto_scalarmult(alice_private.encode(), bob_private.public_key.encode())
-	// box = SecretBox(shared_secret)
+	// h = blake2b(shared_secret,digest_size=32)
+	// key = h.digest()
+	// box = SecretBox(key)
 	// encrypted = box.encrypt(b'hello world')
 	// print(nacl.encoding.HexEncoder().encode(encrypted))
-	// b'74bb3109ad0a1947473ba6bccd3f44a8d735d6a99f8d046dff6e3853b664ad09148a2bf427a95d502c8222b62e4fc8603b2407'
+	// b'8a246cd20d2d29b8f45d7a32e469cd914707bf3abed5747bcd9b54383e56e9be97b940df5a6826400f36a829ce10c618979ee2'
 
 	alicePrivate := ed25519.NewKeyFromSeed([]byte("11111111111111111111111111111111"))
 	bobPrivate := ed25519.NewKeyFromSeed([]byte("22222222222222222222222222222222"))
 
-	encrypted, err := hex.DecodeString("74bb3109ad0a1947473ba6bccd3f44a8d735d6a99f8d046dff6e3853b664ad09148a2bf427a95d502c8222b62e4fc8603b2407")
+	encrypted, err := hex.DecodeString("8a246cd20d2d29b8f45d7a32e469cd914707bf3abed5747bcd9b54383e56e9be97b940df5a6826400f36a829ce10c618979ee2")
 	require.NoError(t, err)
 
 	decrypted, err := DecryptECDH(encrypted, bobPrivate, alicePrivate.Public().(ed25519.PublicKey))