From 58f7b1be1e224083b9f5045a312b67f32bc86ba7 Mon Sep 17 00:00:00 2001 From: Alexander Neumann Date: Sat, 4 Oct 2014 16:57:42 +0200 Subject: [PATCH] Use CTR instead of CBC for encryption --- key.go | 53 ++++++++----------------------------------------- key_int_test.go | 2 +- 2 files changed, 9 insertions(+), 46 deletions(-) diff --git a/key.go b/key.go index 690934d37..d19ff6fdd 100644 --- a/key.go +++ b/key.go @@ -1,7 +1,6 @@ package khepri import ( - "bytes" "crypto/aes" "crypto/cipher" "crypto/hmac" @@ -231,40 +230,6 @@ func (k *Key) newIV() ([]byte, error) { return buf, nil } -func (k *Key) pad(plaintext []byte) []byte { - l := aes.BlockSize - (len(plaintext) % aes.BlockSize) - if l == 0 { - l = aes.BlockSize - } - - if l <= 0 || l > aes.BlockSize { - panic("invalid padding size") - } - - return append(plaintext, bytes.Repeat([]byte{byte(l)}, l)...) -} - -func (k *Key) unpad(plaintext []byte) []byte { - l := len(plaintext) - pad := plaintext[l-1] - - if pad > aes.BlockSize { - panic(errors.New("padding > BlockSize")) - } - - if pad == 0 { - panic(errors.New("invalid padding 0")) - } - - for i := l - int(pad); i < l; i++ { - if plaintext[i] != pad { - panic(errors.New("invalid padding!")) - } - } - - return plaintext[:l-int(pad)] -} - // Encrypt encrypts and signs data. Returned is IV || Ciphertext || HMAC. For // the hash function, SHA256 is used, so the overhead is 16+32=48 byte. func (k *Key) encrypt(ks *keys, plaintext []byte) ([]byte, error) { @@ -278,12 +243,11 @@ func (k *Key) encrypt(ks *keys, plaintext []byte) ([]byte, error) { panic(fmt.Sprintf("unable to create cipher: %v", err)) } - e := cipher.NewCBCEncrypter(c, iv) - p := k.pad(plaintext) - ciphertext := make([]byte, len(p)) - e.CryptBlocks(ciphertext, p) - - ciphertext = append(iv, ciphertext...) + e := cipher.NewCTR(c, iv) + l := len(iv) + ciphertext := make([]byte, l+len(plaintext)) + copy(ciphertext[:l], iv) + e.XORKeyStream(ciphertext[l:], plaintext) hm := hmac.New(sha256.New, ks.Sign) @@ -341,12 +305,11 @@ func (k *Key) decrypt(ks *keys, ciphertext []byte) ([]byte, error) { } // decrypt - e := cipher.NewCBCDecrypter(c, iv) + e := cipher.NewCTR(c, iv) plaintext := make([]byte, len(ciphertext)) - e.CryptBlocks(plaintext, ciphertext) + e.XORKeyStream(plaintext, ciphertext) - // remove padding and return - return k.unpad(plaintext), nil + return plaintext, nil } // Decrypt verifes and decrypts the ciphertext with the master key. Ciphertext diff --git a/key_int_test.go b/key_int_test.go index 06032a83e..232e68590 100644 --- a/key_int_test.go +++ b/key_int_test.go @@ -15,7 +15,7 @@ var test_values = []struct { { ekey: decode_hex("303e8687b1d7db18421bdc6bb8588ccadac4d59ee87b8ff70c44e635790cafef"), skey: decode_hex("cc8d4b948ee0ebfe1d415de921d10353ef4d8824cb80b2bcc5fbff8a9b12a42c"), - ciphertext: decode_hex("154f582d77e6430409da392c3a09aa38e00a78bcc8919557fe18dd17f83e7b0b3053def59f4215b6e1c6b72ceb5acdddd8511ce3a853e054218de1e9f34637470d68f1f93ba8228e4d9817d7c9acfcd2"), + ciphertext: decode_hex("fe85b32b108308f6f8834a96e463b66e0eae6a0f1e9809da0773a2db12a24528bce3220e6a5700b40bd45ef2a2ce96a7fc0a895a019d4a77eef5fc9579297059c6d0"), plaintext: []byte("Dies ist ein Test!"), }, }