From d1f39f841beaad7c9419f90c5efc8f36aa388741 Mon Sep 17 00:00:00 2001 From: Gustav Simonsson Date: Fri, 1 May 2015 08:07:22 +0200 Subject: [PATCH 1/3] Zero XOR CTR IV in ECIES and remove it from ciphertext --- crypto/ecies/ecies.go | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/crypto/ecies/ecies.go b/crypto/ecies/ecies.go index 8125456318..5fff2fa91c 100644 --- a/crypto/ecies/ecies.go +++ b/crypto/ecies/ecies.go @@ -1,6 +1,7 @@ package ecies import ( + "bytes" "crypto/cipher" "crypto/ecdsa" "crypto/elliptic" @@ -185,16 +186,17 @@ func symEncrypt(rand io.Reader, params *ECIESParams, key, m []byte) (ct []byte, if err != nil { return } - - iv, err := generateIV(params, rand) - if err != nil { - return - } + /* + In SEC 1 Version 2.0 the IV value is not specified in for XOR CTR. + It is specified, however, that it should not be transmitted as part of the ciphertext. + This means it cannot be random, as the other party would not know the value. + Therefore we set it to the zeroed value defined for AES in CTR mode. + */ + iv := bytes.Repeat([]byte{0}, 16) ctr := cipher.NewCTR(c, iv) - ct = make([]byte, len(m)+params.BlockSize) - copy(ct, iv) - ctr.XORKeyStream(ct[params.BlockSize:], m) + ct = make([]byte, len(m)) + ctr.XORKeyStream(ct, m) return } @@ -206,10 +208,11 @@ func symDecrypt(rand io.Reader, params *ECIESParams, key, ct []byte) (m []byte, return } - ctr := cipher.NewCTR(c, ct[:params.BlockSize]) + iv := bytes.Repeat([]byte{0}, 16) + ctr := cipher.NewCTR(c, iv) - m = make([]byte, len(ct)-params.BlockSize) - ctr.XORKeyStream(m, ct[params.BlockSize:]) + m = make([]byte, len(ct)) + ctr.XORKeyStream(m, ct) return } @@ -245,7 +248,7 @@ func Encrypt(rand io.Reader, pub *PublicKey, m, s1, s2 []byte) (ct []byte, err e hash.Reset() em, err := symEncrypt(rand, params, Ke, m) - if err != nil || len(em) <= params.BlockSize { + if err != nil { return } From 0b6a702f245b9bc44f5396d700f8fa150e9bd885 Mon Sep 17 00:00:00 2001 From: Gustav Simonsson Date: Fri, 1 May 2015 08:12:42 +0200 Subject: [PATCH 2/3] Remove hashing of MAC key part of KDF derived key --- crypto/ecies/ecies.go | 6 ------ 1 file changed, 6 deletions(-) diff --git a/crypto/ecies/ecies.go b/crypto/ecies/ecies.go index 5fff2fa91c..ebdc4e2635 100644 --- a/crypto/ecies/ecies.go +++ b/crypto/ecies/ecies.go @@ -243,9 +243,6 @@ func Encrypt(rand io.Reader, pub *PublicKey, m, s1, s2 []byte) (ct []byte, err e } Ke := K[:params.KeyLen] Km := K[params.KeyLen:] - hash.Write(Km) - Km = hash.Sum(nil) - hash.Reset() em, err := symEncrypt(rand, params, Ke, m) if err != nil { @@ -323,9 +320,6 @@ func (prv *PrivateKey) Decrypt(rand io.Reader, c, s1, s2 []byte) (m []byte, err Ke := K[:params.KeyLen] Km := K[params.KeyLen:] - hash.Write(Km) - Km = hash.Sum(nil) - hash.Reset() d := messageTag(params.Hash, Km, c[mStart:mEnd], s2) if subtle.ConstantTimeCompare(c[mEnd:], d) != 1 { From 8f652287bd2457ab22c6a27bc97f9f2949a45493 Mon Sep 17 00:00:00 2001 From: Gustav Simonsson Date: Fri, 1 May 2015 08:14:27 +0200 Subject: [PATCH 3/3] Add SEC 1 section to comment about IV --- crypto/ecies/ecies.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crypto/ecies/ecies.go b/crypto/ecies/ecies.go index ebdc4e2635..4be91dd3d7 100644 --- a/crypto/ecies/ecies.go +++ b/crypto/ecies/ecies.go @@ -187,7 +187,7 @@ func symEncrypt(rand io.Reader, params *ECIESParams, key, m []byte) (ct []byte, return } /* - In SEC 1 Version 2.0 the IV value is not specified in for XOR CTR. + In SEC 1 Version 2.0 section 3.8 the IV value is not specified in for XOR CTR. It is specified, however, that it should not be transmitted as part of the ciphertext. This means it cannot be random, as the other party would not know the value. Therefore we set it to the zeroed value defined for AES in CTR mode.