xts: fix incorrect length check
This change does two things: 1. Fix a length checking bug in the Decrypt function. 2. Use binary.LittleEndian for byte conversions. Fixes golang/go#19881 Change-Id: I9d33b92f2bd7e6ca8f69308388f1e8a5c6df2be8 Reviewed-on: https://go-review.googlesource.com/39954 Reviewed-by: Adam Langley <agl@golang.org>
This commit is contained in:
committed by
Adam Langley
parent
080743b219
commit
976dfd0a58
+19
-20
@@ -23,6 +23,7 @@ package xts // import "golang.org/x/crypto/xts"
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/cipher"
|
"crypto/cipher"
|
||||||
|
"encoding/binary"
|
||||||
"errors"
|
"errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -65,21 +66,20 @@ func (c *Cipher) Encrypt(ciphertext, plaintext []byte, sectorNum uint64) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var tweak [blockSize]byte
|
var tweak [blockSize]byte
|
||||||
for i := 0; i < 8; i++ {
|
binary.LittleEndian.PutUint64(tweak[:8], sectorNum)
|
||||||
tweak[i] = byte(sectorNum)
|
|
||||||
sectorNum >>= 8
|
|
||||||
}
|
|
||||||
|
|
||||||
c.k2.Encrypt(tweak[:], tweak[:])
|
c.k2.Encrypt(tweak[:], tweak[:])
|
||||||
|
|
||||||
for i := 0; i < len(plaintext); i += blockSize {
|
for len(plaintext) > 0 {
|
||||||
for j := 0; j < blockSize; j++ {
|
for j := range tweak {
|
||||||
ciphertext[i+j] = plaintext[i+j] ^ tweak[j]
|
ciphertext[j] = plaintext[j] ^ tweak[j]
|
||||||
}
|
}
|
||||||
c.k1.Encrypt(ciphertext[i:], ciphertext[i:])
|
c.k1.Encrypt(ciphertext, ciphertext)
|
||||||
for j := 0; j < blockSize; j++ {
|
for j := range tweak {
|
||||||
ciphertext[i+j] ^= tweak[j]
|
ciphertext[j] ^= tweak[j]
|
||||||
}
|
}
|
||||||
|
plaintext = plaintext[blockSize:]
|
||||||
|
ciphertext = ciphertext[blockSize:]
|
||||||
|
|
||||||
mul2(&tweak)
|
mul2(&tweak)
|
||||||
}
|
}
|
||||||
@@ -97,21 +97,20 @@ func (c *Cipher) Decrypt(plaintext, ciphertext []byte, sectorNum uint64) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var tweak [blockSize]byte
|
var tweak [blockSize]byte
|
||||||
for i := 0; i < 8; i++ {
|
binary.LittleEndian.PutUint64(tweak[:8], sectorNum)
|
||||||
tweak[i] = byte(sectorNum)
|
|
||||||
sectorNum >>= 8
|
|
||||||
}
|
|
||||||
|
|
||||||
c.k2.Encrypt(tweak[:], tweak[:])
|
c.k2.Encrypt(tweak[:], tweak[:])
|
||||||
|
|
||||||
for i := 0; i < len(plaintext); i += blockSize {
|
for len(ciphertext) > 0 {
|
||||||
for j := 0; j < blockSize; j++ {
|
for j := range tweak {
|
||||||
plaintext[i+j] = ciphertext[i+j] ^ tweak[j]
|
plaintext[j] = ciphertext[j] ^ tweak[j]
|
||||||
}
|
}
|
||||||
c.k1.Decrypt(plaintext[i:], plaintext[i:])
|
c.k1.Decrypt(plaintext, plaintext)
|
||||||
for j := 0; j < blockSize; j++ {
|
for j := range tweak {
|
||||||
plaintext[i+j] ^= tweak[j]
|
plaintext[j] ^= tweak[j]
|
||||||
}
|
}
|
||||||
|
plaintext = plaintext[blockSize:]
|
||||||
|
ciphertext = ciphertext[blockSize:]
|
||||||
|
|
||||||
mul2(&tweak)
|
mul2(&tweak)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -83,3 +83,23 @@ func TestXTS(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestShorterCiphertext(t *testing.T) {
|
||||||
|
// Decrypt used to panic if the input was shorter than the output. See
|
||||||
|
// https://go-review.googlesource.com/c/39954/
|
||||||
|
c, err := NewCipher(aes.NewCipher, make([]byte, 32))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("NewCipher failed: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
plaintext := make([]byte, 32)
|
||||||
|
encrypted := make([]byte, 48)
|
||||||
|
decrypted := make([]byte, 48)
|
||||||
|
|
||||||
|
c.Encrypt(encrypted, plaintext, 0)
|
||||||
|
c.Decrypt(decrypted, encrypted[:len(plaintext)], 0)
|
||||||
|
|
||||||
|
if !bytes.Equal(plaintext, decrypted[:len(plaintext)]) {
|
||||||
|
t.Errorf("En/Decryption is not inverse")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user