func benchmarkEncrypt( b *testing.B, size int) { var err error // Generate the appropriate amount of random data. plaintext := make([]byte, size) _, err = rand.Read(plaintext) if err != nil { b.Fatalf("rand.Read: %v", err) } // Create a random key. const keyLen = 32 key := make([]byte, keyLen) _, err = rand.Read(key) if err != nil { b.Fatalf("rand.Read: %v", err) } // Repeatedly encrypt. b.ResetTimer() for i := 0; i < b.N; i++ { _, err = siv.Encrypt(nil, key, plaintext, nil) if err != nil { b.Fatalf("Encrypt: %v", err) } } b.SetBytes(int64(size)) }
// Print a single test case to STDOUT. func printTestCase(key []byte, plaintext []byte, associatedData [][]byte) { // CTR mode encryption key fmt.Println(hex.EncodeToString(key[len(key)/2:])) // MAC (authentication) key fmt.Println(hex.EncodeToString(key[:len(key)/2])) // Plaintext fmt.Println(hex.EncodeToString(plaintext)) // Additional associated data fmt.Printf("%v\n", len(associatedData)) for _, adElem := range associatedData { fmt.Println(hex.EncodeToString(adElem)) } // Ciphertext ciphertext, err := siv.Encrypt(nil, key, plaintext, associatedData) if err != nil { fmt.Println("encrypt failed: ", err) os.Exit(7) } fmt.Println(hex.EncodeToString(ciphertext)) // End of test case fmt.Println("---") }
func (t *EncryptTest) LongKey() { key := make([]byte, 65) plaintext := []byte{} _, err := siv.Encrypt(nil, key, plaintext, nil) ExpectThat(err, Error(HasSubstr("-byte"))) }
func (t *EncryptTest) Rfc5297TestCaseA2() { key := aes_testing.FromRfcHex( "7f7e7d7c 7b7a7978 77767574 73727170" + "40414243 44454647 48494a4b 4c4d4e4f") plaintext := aes_testing.FromRfcHex( "74686973 20697320 736f6d65 20706c61" + "696e7465 78742074 6f20656e 63727970" + "74207573 696e6720 5349562d 414553") associated := [][]byte{ aes_testing.FromRfcHex( "00112233 44556677 8899aabb ccddeeff" + "deaddada deaddada ffeeddcc bbaa9988" + "77665544 33221100"), aes_testing.FromRfcHex( "10203040 50607080 90a0"), aes_testing.FromRfcHex( "09f91102 9d74e35b d84156c5 635688c0"), } expected := aes_testing.FromRfcHex( "7bdb6e3b 432667eb 06f4d14b ff2fbd0f" + "cb900f2f ddbe4043 26601965 c889bf17" + "dba77ceb 094fa663 b7a3f748 ba8af829" + "ea64ad54 4a272e9c 485b62a3 fd5c0d") output, err := siv.Encrypt(nil, key, plaintext, associated) AssertEq(nil, err) ExpectThat(output, DeepEquals(expected)) }
func (t *EncryptTest) JustLittleEnoughAssociatedData() { key := make([]byte, 64) plaintext := []byte{} associated := make([][]byte, 126) _, err := siv.Encrypt(nil, key, plaintext, associated) ExpectEq(nil, err) }
func (t *EncryptTest) TooMuchAssociatedData() { key := make([]byte, 64) plaintext := []byte{} associated := make([][]byte, 127) _, err := siv.Encrypt(nil, key, plaintext, associated) ExpectThat(err, Error(HasSubstr("associated"))) ExpectThat(err, Error(HasSubstr("126"))) }
func (t *EncryptTest) OutputIsDeterministic() { cases := aes_testing.EncryptCases() AssertGt(len(cases), 37) c := cases[37] output0, err := siv.Encrypt(nil, c.Key, c.Plaintext, c.Associated) AssertEq(nil, err) output1, err := siv.Encrypt(nil, c.Key, c.Plaintext, c.Associated) AssertEq(nil, err) output2, err := siv.Encrypt(nil, c.Key, c.Plaintext, c.Associated) AssertEq(nil, err) AssertGt(len(output0), 0) ExpectThat(output0, DeepEquals(output1)) ExpectThat(output0, DeepEquals(output2)) }
// 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") } }
func (t *EncryptTest) GeneratedTestCases() { cases := aes_testing.EncryptCases() AssertGe(len(cases), 100) for i, c := range cases { output, err := siv.Encrypt(nil, c.Key, c.Plaintext, c.Associated) AssertEq(nil, err, "Case %d: %v", i, c) ExpectThat(output, DeepEquals(c.Output), "Case %d: %v", i, c) } }
func EncryptInvocations(cmds g.Invocations, key []byte) (g.Invocations, error) { dst := make([]byte, 0) assoc := make([][]byte, 0) for i, c := range cmds { com, err := siv.Encrypt(dst, key, []byte(c.Command), assoc) dir, err := siv.Encrypt(dst, key, []byte(c.Directory), assoc) host, err := siv.Encrypt(dst, key, []byte(c.Host), assoc) shell, err := siv.Encrypt(dst, key, []byte(c.Shell), assoc) user, err := siv.Encrypt(dst, key, []byte(c.User), assoc) tags := make([]string, 0) for _, tag := range c.Tags { t, err := siv.Encrypt(dst, key, []byte(tag), assoc) if err != nil { return nil, err } tags = append(tags, string(t)) } if err != nil { return nil, err } cmds[i].Command = string(com) cmds[i].Directory = string(dir) cmds[i].Host = string(host) cmds[i].Shell = string(shell) cmds[i].User = string(user) cmds[i].Tags = tags } return cmds, nil }
// Seal encrypts "in" using "nonce" and "authData" and append the result to "dst" func (s *sivAead) Seal(dst, nonce, plaintext, authData []byte) []byte { if len(nonce) != 16 { // SIV supports any nonce size, but in gocryptfs we exclusively use 16. log.Panic("nonce must be 16 bytes long") } // https://github.com/jacobsa/crypto/blob/master/siv/encrypt.go#L48: // As per RFC 5297 section 3, you may use this function for nonce-based // authenticated encryption by passing a nonce as the last associated // data element. associated := [][]byte{authData, nonce} out, err := siv.Encrypt(dst, s.key, plaintext, associated) if err != nil { log.Panic(err) } return out }
// 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") } } }
func (t *EncryptTest) DoesntClobberAssociatedSlice() { key := make([]byte, 32) plaintext := []byte{} associated0 := aes_testing.FromRfcHex("deadbeef") associated1 := aes_testing.FromRfcHex("feedface") associated2 := aes_testing.FromRfcHex("ba5eba11") associated := [][]byte{associated0, associated1, associated2} // Call with a slice of associated missing the last element. The last element // shouldn't be clobbered. _, err := siv.Encrypt(nil, key, plaintext, associated[:2]) AssertEq(nil, err) ExpectThat( associated, ElementsAre( DeepEquals(associated0), DeepEquals(associated1), DeepEquals(associated2), )) }
func (t *EncryptTest) Rfc5297TestCaseA1() { key := aes_testing.FromRfcHex( "fffefdfc fbfaf9f8 f7f6f5f4 f3f2f1f0" + "f0f1f2f3 f4f5f6f7 f8f9fafb fcfdfeff") plaintext := aes_testing.FromRfcHex( "11223344 55667788 99aabbcc ddee") associated := [][]byte{ aes_testing.FromRfcHex( "10111213 14151617 18191a1b 1c1d1e1f" + "20212223 24252627"), } expected := aes_testing.FromRfcHex( "85632d07 c6e8f37f 950acd32 0a2ecc93" + "40c02b96 90c4dc04 daef7f6a fe5c") output, err := siv.Encrypt(nil, key, plaintext, associated) AssertEq(nil, err) ExpectThat(output, DeepEquals(expected)) }
func (c *sivCrypter) Encrypt(dst, plaintext []byte) ([]byte, error) { return siv.Encrypt(dst, c.key, plaintext, nil) }