diff --git a/internal/siv_aead/correctness_test.go b/internal/siv_aead/correctness_test.go index c271970..a9885e7 100644 --- a/internal/siv_aead/correctness_test.go +++ b/internal/siv_aead/correctness_test.go @@ -8,7 +8,31 @@ import ( "github.com/jacobsa/crypto/siv" ) -func TestAll(t *testing.T) { +// Test all supported key lengths +func TestKeyLens(t *testing.T) { + keyLens := []int{32, 48, 64} + nonce := make([]byte, 16) + plaintext := []byte("foobar") + for _, keyLen := range keyLens { + key := make([]byte, keyLen) + a := New(key) + ciphertext2 := a.Seal(nil, nonce, plaintext, nil) + + ciphertext, err := siv.Encrypt(nil, key, plaintext, [][]byte{nil, nonce}) + if err != nil { + t.Error(err) + } else if o := len(ciphertext) - len(plaintext); o != a.Overhead() { + t.Errorf("keyLen=%d, actual overhead: %d\n", keyLen, o) + } + if !bytes.Equal(ciphertext, ciphertext2) { + t.Errorf("siv and siv_aead produce different results") + } + } + +} + +// Test using a 32-byte key +func TestK32(t *testing.T) { key := bytes.Repeat([]byte{1}, 32) nonce := bytes.Repeat([]byte{2}, 16) plaintext := []byte{1, 2, 3, 4, 5, 6, 7, 8, 9} @@ -64,3 +88,61 @@ func TestAll(t *testing.T) { t.Error("should have failed") } } + +// Test using a 64-byte key +func TestK64(t *testing.T) { + key := bytes.Repeat([]byte{1}, 64) + nonce := bytes.Repeat([]byte{2}, 16) + plaintext := []byte{1, 2, 3, 4, 5, 6, 7, 8, 9} + aData := make([]byte, 24) + // Compare siv and siv_aead results + sResult, err := siv.Encrypt(nonce, key, plaintext, [][]byte{aData, nonce}) + if err != nil { + t.Fatal(err) + } + a := New(key) + aResult := a.Seal(nonce, nonce, plaintext, aData) + if !bytes.Equal(sResult, aResult) { + t.Errorf("siv and siv_aead produce different results") + } + expectedResult, _ := hex.DecodeString( + "02020202020202020202020202020202317b316f67c3ad336c01c9a01b4c5e552ba89e966bc4c1ade1") + if !bytes.Equal(aResult, expectedResult) { + t.Errorf(hex.EncodeToString(aResult)) + } + // Verify overhead + overhead := len(aResult) - len(plaintext) - len(nonce) + if overhead != a.Overhead() { + t.Errorf("Overhead() returns a wrong value") + } + // Decrypt + p1, err := a.Open(nil, aResult[:16], aResult[16:], aData) + if err != nil { + t.Error(err) + } + if !bytes.Equal(plaintext, p1) { + t.Errorf("wrong plaintext") + } + // Decrypt and append + dst := []byte{0xaa, 0xbb, 0xcc} + p2, err := a.Open(dst, aResult[:16], aResult[16:], aData) + if err != nil { + t.Error(err) + } + p2e := append(dst, plaintext...) + if !bytes.Equal(p2e, p2) { + t.Errorf("wrong plaintext: %s", hex.EncodeToString(p2)) + } + // Decrypt corrupt + aResult[17] = 0 + _, err = a.Open(nil, aResult[:16], aResult[16:], aData) + if err == nil { + t.Error("should have failed") + } + // Decrypt and append corrupt + aResult[17] = 0 + _, err = a.Open(dst, aResult[:16], aResult[16:], aData) + if err == nil { + t.Error("should have failed") + } +} diff --git a/internal/siv_aead/siv_aead.go b/internal/siv_aead/siv_aead.go index 21106a5..a0ed882 100644 --- a/internal/siv_aead/siv_aead.go +++ b/internal/siv_aead/siv_aead.go @@ -22,11 +22,7 @@ func (s *sivAead) NonceSize() int { } func (s *sivAead) Overhead() int { - // RFC5297: - // [...] the key length used by AES in CTR and S2V is len(K)/2 and will - // each be either 128 bits, 192 bits, or 256 bits. - return len(s.key) / 2 - + return 16 } // Seal - encrypt "in" using "nonce" and "authData" and append the result to "dst"