summaryrefslogtreecommitdiff
path: root/src/mongo/gotools/vendor/src/github.com/10gen/openssl/ciphers_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/gotools/vendor/src/github.com/10gen/openssl/ciphers_test.go')
-rw-r--r--src/mongo/gotools/vendor/src/github.com/10gen/openssl/ciphers_test.go307
1 files changed, 307 insertions, 0 deletions
diff --git a/src/mongo/gotools/vendor/src/github.com/10gen/openssl/ciphers_test.go b/src/mongo/gotools/vendor/src/github.com/10gen/openssl/ciphers_test.go
new file mode 100644
index 00000000000..96b16817f9d
--- /dev/null
+++ b/src/mongo/gotools/vendor/src/github.com/10gen/openssl/ciphers_test.go
@@ -0,0 +1,307 @@
+// Copyright (C) 2017. See AUTHORS.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// +build !openssl_pre_1.0
+
+package openssl
+
+import (
+ "bytes"
+ "fmt"
+ "strings"
+ "testing"
+)
+
+func expectError(t *testing.T, err error, msg string) {
+ if err == nil {
+ t.Fatalf("Expected error containing %#v, but got none", msg)
+ }
+ if !strings.Contains(err.Error(), msg) {
+ t.Fatalf("Expected error containing %#v, but got %s", msg, err)
+ }
+}
+
+func TestBadInputs(t *testing.T) {
+ _, err := NewGCMEncryptionCipherCtx(256, nil,
+ []byte("abcdefghijklmnopqrstuvwxyz"), nil)
+ expectError(t, err, "bad key size")
+ _, err = NewGCMEncryptionCipherCtx(128, nil,
+ []byte("abcdefghijklmnopqrstuvwxyz"), nil)
+ expectError(t, err, "bad key size")
+ _, err = NewGCMEncryptionCipherCtx(200, nil,
+ []byte("abcdefghijklmnopqrstuvwxy"), nil)
+ expectError(t, err, "unknown block size")
+ c, err := GetCipherByName("AES-128-CBC")
+ if err != nil {
+ t.Fatal("Could not look up AES-128-CBC")
+ }
+ _, err = NewEncryptionCipherCtx(c, nil, []byte("abcdefghijklmnop"),
+ []byte("abc"))
+ expectError(t, err, "bad IV size")
+}
+
+func doEncryption(key, iv, aad, plaintext []byte, blocksize, bufsize int) (
+ ciphertext, tag []byte, err error) {
+ ectx, err := NewGCMEncryptionCipherCtx(blocksize, nil, key, iv)
+ if err != nil {
+ return nil, nil, fmt.Errorf("Failed making GCM encryption ctx: %s", err)
+ }
+ err = ectx.ExtraData(aad)
+ if err != nil {
+ return nil, nil, fmt.Errorf("Failed to add authenticated data: %s",
+ err)
+ }
+ plainb := bytes.NewBuffer(plaintext)
+ cipherb := new(bytes.Buffer)
+ for plainb.Len() > 0 {
+ moar, err := ectx.EncryptUpdate(plainb.Next(bufsize))
+ if err != nil {
+ return nil, nil, fmt.Errorf("Failed to perform an encryption: %s",
+ err)
+ }
+ cipherb.Write(moar)
+ }
+ moar, err := ectx.EncryptFinal()
+ if err != nil {
+ return nil, nil, fmt.Errorf("Failed to finalize encryption: %s", err)
+ }
+ cipherb.Write(moar)
+ tag, err = ectx.GetTag()
+ if err != nil {
+ return nil, nil, fmt.Errorf("Failed to get GCM tag: %s", err)
+ }
+ return cipherb.Bytes(), tag, nil
+}
+
+func doDecryption(key, iv, aad, ciphertext, tag []byte, blocksize,
+ bufsize int) (plaintext []byte, err error) {
+ dctx, err := NewGCMDecryptionCipherCtx(blocksize, nil, key, iv)
+ if err != nil {
+ return nil, fmt.Errorf("Failed making GCM decryption ctx: %s", err)
+ }
+ aadbuf := bytes.NewBuffer(aad)
+ for aadbuf.Len() > 0 {
+ err = dctx.ExtraData(aadbuf.Next(bufsize))
+ if err != nil {
+ return nil, fmt.Errorf("Failed to add authenticated data: %s", err)
+ }
+ }
+ plainb := new(bytes.Buffer)
+ cipherb := bytes.NewBuffer(ciphertext)
+ for cipherb.Len() > 0 {
+ moar, err := dctx.DecryptUpdate(cipherb.Next(bufsize))
+ if err != nil {
+ return nil, fmt.Errorf("Failed to perform a decryption: %s", err)
+ }
+ plainb.Write(moar)
+ }
+ err = dctx.SetTag(tag)
+ if err != nil {
+ return nil, fmt.Errorf("Failed to set expected GCM tag: %s", err)
+ }
+ moar, err := dctx.DecryptFinal()
+ if err != nil {
+ return nil, fmt.Errorf("Failed to finalize decryption: %s", err)
+ }
+ plainb.Write(moar)
+ return plainb.Bytes(), nil
+}
+
+func checkEqual(t *testing.T, output []byte, original string) {
+ output_s := string(output)
+ if output_s != original {
+ t.Fatalf("output != original! %#v != %#v", output_s, original)
+ }
+}
+
+func TestGCM(t *testing.T) {
+ aad := []byte("foo bar baz")
+ key := []byte("nobody can guess this i'm sure..") // len=32
+ iv := []byte("just a bunch of bytes")
+ plaintext := "Long long ago, in a land far away..."
+
+ blocksizes_to_test := []int{256, 192, 128}
+
+ // best for this to have no common factors with blocksize, so that the
+ // buffering layer inside the CIPHER_CTX gets exercised
+ bufsize := 33
+
+ if len(plaintext)%8 == 0 {
+ plaintext += "!" // make sure padding is exercised
+ }
+
+ for _, bsize := range blocksizes_to_test {
+ subkey := key[:bsize/8]
+ ciphertext, tag, err := doEncryption(subkey, iv, aad, []byte(plaintext),
+ bsize, bufsize)
+ if err != nil {
+ t.Fatalf("Encryption with b=%d: %s", bsize, err)
+ }
+ plaintext_out, err := doDecryption(subkey, iv, aad, ciphertext, tag,
+ bsize, bufsize)
+ if err != nil {
+ t.Fatalf("Decryption with b=%d: %s", bsize, err)
+ }
+ checkEqual(t, plaintext_out, plaintext)
+ }
+}
+
+func TestGCMWithNoAAD(t *testing.T) {
+ key := []byte("0000111122223333")
+ iv := []byte("9999")
+ plaintext := "ABORT ABORT ABORT DANGAR"
+
+ ciphertext, tag, err := doEncryption(key, iv, nil, []byte(plaintext),
+ 128, 32)
+ if err != nil {
+ t.Fatal("Encryption failure:", err)
+ }
+ plaintext_out, err := doDecryption(key, iv, nil, ciphertext, tag, 128, 129)
+ if err != nil {
+ t.Fatal("Decryption failure:", err)
+ }
+ checkEqual(t, plaintext_out, plaintext)
+}
+
+func TestBadTag(t *testing.T) {
+ key := []byte("abcdefghijklmnop")
+ iv := []byte("v7239qjfv3qr793fuaj")
+ plaintext := "The red rooster has flown the coop I REPEAT" +
+ "the red rooster has flown the coop!!1!"
+
+ ciphertext, tag, err := doEncryption(key, iv, nil, []byte(plaintext),
+ 128, 32)
+ if err != nil {
+ t.Fatal("Encryption failure:", err)
+ }
+ // flip the last bit
+ tag[len(tag)-1] ^= 1
+ plaintext_out, err := doDecryption(key, iv, nil, ciphertext, tag, 128, 129)
+ if err == nil {
+ t.Fatal("Expected error for bad tag, but got none")
+ }
+ // flip it back, try again just to make sure
+ tag[len(tag)-1] ^= 1
+ plaintext_out, err = doDecryption(key, iv, nil, ciphertext, tag, 128, 129)
+ if err != nil {
+ t.Fatal("Decryption failure:", err)
+ }
+ checkEqual(t, plaintext_out, plaintext)
+}
+
+func TestBadCiphertext(t *testing.T) {
+ key := []byte("hard boiled eggs & bacon")
+ iv := []byte("x") // it's not a very /good/ IV, is it
+ aad := []byte("mu")
+ plaintext := "Roger roger bingo charlie, we have a niner fourteen tango"
+
+ ciphertext, tag, err := doEncryption(key, iv, aad, []byte(plaintext),
+ 192, 1)
+ if err != nil {
+ t.Fatal("Encryption failure:", err)
+ }
+ // flip the last bit
+ ciphertext[len(ciphertext)-1] ^= 1
+ plaintext_out, err := doDecryption(key, iv, aad, ciphertext, tag, 192, 192)
+ if err == nil {
+ t.Fatal("Expected error for bad ciphertext, but got none")
+ }
+ // flip it back, try again just to make sure
+ ciphertext[len(ciphertext)-1] ^= 1
+ plaintext_out, err = doDecryption(key, iv, aad, ciphertext, tag, 192, 192)
+ if err != nil {
+ t.Fatal("Decryption failure:", err)
+ }
+ checkEqual(t, plaintext_out, plaintext)
+}
+
+func TestBadAAD(t *testing.T) {
+ key := []byte("Ive got a lovely buncha coconuts")
+ iv := []byte("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab")
+ aad := []byte("Hi i am a plain")
+ plaintext := "Whatever."
+
+ ciphertext, tag, err := doEncryption(key, iv, aad, []byte(plaintext),
+ 256, 256)
+ if err != nil {
+ t.Fatal("Encryption failure:", err)
+ }
+ // flip the last bit
+ aad[len(aad)-1] ^= 1
+ plaintext_out, err := doDecryption(key, iv, aad, ciphertext, tag, 256, 256)
+ if err == nil {
+ t.Fatal("Expected error for bad AAD, but got none")
+ }
+ // flip it back, try again just to make sure
+ aad[len(aad)-1] ^= 1
+ plaintext_out, err = doDecryption(key, iv, aad, ciphertext, tag, 256, 256)
+ if err != nil {
+ t.Fatal("Decryption failure:", err)
+ }
+ checkEqual(t, plaintext_out, plaintext)
+}
+
+func TestNonAuthenticatedEncryption(t *testing.T) {
+ key := []byte("never gonna give you up, never g")
+ iv := []byte("onna let you dow")
+ plaintext1 := "n, never gonna run around"
+ plaintext2 := " and desert you"
+
+ cipher, err := GetCipherByName("aes-256-cbc")
+ if err != nil {
+ t.Fatal("Could not get cipher: ", err)
+ }
+
+ eCtx, err := NewEncryptionCipherCtx(cipher, nil, key, iv)
+ if err != nil {
+ t.Fatal("Could not create encryption context: ", err)
+ }
+ cipherbytes, err := eCtx.EncryptUpdate([]byte(plaintext1))
+ if err != nil {
+ t.Fatal("EncryptUpdate(plaintext1) failure: ", err)
+ }
+ ciphertext := string(cipherbytes)
+ cipherbytes, err = eCtx.EncryptUpdate([]byte(plaintext2))
+ if err != nil {
+ t.Fatal("EncryptUpdate(plaintext2) failure: ", err)
+ }
+ ciphertext += string(cipherbytes)
+ cipherbytes, err = eCtx.EncryptFinal()
+ if err != nil {
+ t.Fatal("EncryptFinal() failure: ", err)
+ }
+ ciphertext += string(cipherbytes)
+
+ dCtx, err := NewDecryptionCipherCtx(cipher, nil, key, iv)
+ if err != nil {
+ t.Fatal("Could not create decryption context: ", err)
+ }
+ plainbytes, err := dCtx.DecryptUpdate([]byte(ciphertext[:15]))
+ if err != nil {
+ t.Fatal("DecryptUpdate(ciphertext part 1) failure: ", err)
+ }
+ plainOutput := string(plainbytes)
+ plainbytes, err = dCtx.DecryptUpdate([]byte(ciphertext[15:]))
+ if err != nil {
+ t.Fatal("DecryptUpdate(ciphertext part 2) failure: ", err)
+ }
+ plainOutput += string(plainbytes)
+ plainbytes, err = dCtx.DecryptFinal()
+ if err != nil {
+ t.Fatal("DecryptFinal() failure: ", err)
+ }
+ plainOutput += string(plainbytes)
+
+ checkEqual(t, []byte(plainOutput), plaintext1+plaintext2)
+}