diff --git a/cng/aes_test.go b/cng/aes_test.go index afbac19..381f2aa 100644 --- a/cng/aes_test.go +++ b/cng/aes_test.go @@ -4,28 +4,34 @@ //go:build windows // +build windows -package cng +package cng_test import ( "bytes" "crypto/cipher" "fmt" - "io" - "math/rand" + "strings" "testing" - "time" + "github.com/microsoft/go-crypto-winnative/cng" "github.com/microsoft/go-crypto-winnative/internal/cryptotest" ) var key = []byte("D249BF6DEC97B1EBD69BC4D6B3A3C49D") +const ( + gcmTagSize = 16 + gcmStandardNonceSize = 12 +) + func TestNewGCMNonce(t *testing.T) { - ci, err := NewAESCipher(key) + ci, err := cng.NewAESCipher(key) if err != nil { t.Fatal(err) } - c := ci.(*aesCipher) + c := ci.(interface { + NewGCM(nonceSize, tagSize int) (cipher.AEAD, error) + }) _, err = c.NewGCM(gcmStandardNonceSize-1, gcmTagSize-1) if err == nil { t.Error("expected error for non-standard tag and nonce size at the same time, got none") @@ -45,12 +51,11 @@ func TestNewGCMNonce(t *testing.T) { } func TestSealAndOpen(t *testing.T) { - ci, err := NewAESCipher(key) + ci, err := cng.NewAESCipher(key) if err != nil { t.Fatal(err) } - c := ci.(*aesCipher) - gcm, err := c.NewGCM(gcmStandardNonceSize, gcmTagSize) + gcm, err := cipher.NewGCMWithTagSize(ci, gcmTagSize) if err != nil { t.Fatal(err) } @@ -95,16 +100,16 @@ func TestSealAndOpenTLS(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - ci, err := NewAESCipher(key) + ci, err := cng.NewAESCipher(key) if err != nil { t.Fatal(err) } var gcm cipher.AEAD switch tt.tls { case "1.2": - gcm, err = NewGCMTLS(ci) + gcm, err = cng.NewGCMTLS(ci) case "1.3": - gcm, err = NewGCMTLS13(ci) + gcm, err = cng.NewGCMTLS13(ci) } if err != nil { t.Fatal(err) @@ -163,12 +168,11 @@ func TestSealAndOpenTLS(t *testing.T) { } func TestSealAndOpenAuthenticationError(t *testing.T) { - ci, err := NewAESCipher(key) + ci, err := cng.NewAESCipher(key) if err != nil { t.Fatal(err) } - c := ci.(*aesCipher) - gcm, err := c.NewGCM(gcmStandardNonceSize, gcmTagSize) + gcm, err := cipher.NewGCMWithTagSize(ci, gcmTagSize) if err != nil { t.Fatal(err) } @@ -177,7 +181,7 @@ func TestSealAndOpenAuthenticationError(t *testing.T) { additionalData := []byte{0x05, 0x05, 0x07} sealed := gcm.Seal(nil, nonce, plainText, additionalData) _, err = gcm.Open(nil, nonce, sealed, nil) - if err != errOpen { + if !strings.Contains(err.Error(), "cipher: message authentication failed") { t.Errorf("expected authentication error, got: %#v", err) } } @@ -193,12 +197,11 @@ func assertPanic(t *testing.T, f func()) { } func TestSealPanic(t *testing.T) { - ci, err := NewAESCipher(key) + ci, err := cng.NewAESCipher(key) if err != nil { t.Fatal(err) } - c := ci.(*aesCipher) - gcm, err := c.NewGCM(gcmStandardNonceSize, gcmTagSize) + gcm, err := cipher.NewGCMWithTagSize(ci, gcmTagSize) if err != nil { t.Fatal(err) } @@ -215,14 +218,14 @@ func TestSealPanic(t *testing.T) { } func TestAESInvalidKeySize(t *testing.T) { - _, err := NewAESCipher([]byte{1}) + _, err := cng.NewAESCipher([]byte{1}) if err == nil { t.Error("error expected") } } func TestEncryptAndDecrypt(t *testing.T) { - ci, err := NewAESCipher(key) + ci, err := cng.NewAESCipher(key) if err != nil { t.Fatal(err) } @@ -242,7 +245,7 @@ func TestCBCBlobEncryptBasicBlockEncryption(t *testing.T) { key := []byte{0x24, 0xcd, 0x8b, 0x13, 0x37, 0xc5, 0xc1, 0xb1, 0x0, 0xbb, 0x27, 0x40, 0x4f, 0xab, 0x5f, 0x7b, 0x2d, 0x0, 0x20, 0xf5, 0x1, 0x84, 0x4, 0xbf, 0xe3, 0xbd, 0xa1, 0xc4, 0xbf, 0x61, 0x2f, 0xc5} iv := []byte{0x91, 0xc7, 0xa7, 0x54, 0x52, 0xef, 0x10, 0xdb, 0x91, 0xa8, 0x6c, 0xf9, 0x79, 0xd5, 0xac, 0x74} - block, err := NewAESCipher(key) + block, err := cng.NewAESCipher(key) if err != nil { t.Errorf("expected no error for aes.NewCipher, got: %s", err) } @@ -251,19 +254,14 @@ func TestCBCBlobEncryptBasicBlockEncryption(t *testing.T) { if blockSize != 16 { t.Errorf("unexpected block size, expected 16 got: %d", blockSize) } - var encryptor cipher.BlockMode - if c, ok := block.(*aesCipher); ok { - encryptor = c.NewCBCEncrypter(iv) - if encryptor == nil { - t.Error("unable to create new CBC encrypter") - } - } + + encrypter := cipher.NewCBCEncrypter(block, iv) encrypted := make([]byte, 32) // First block. 16 bytes. srcBlock1 := bytes.Repeat([]byte{0x01}, 16) - encryptor.CryptBlocks(encrypted, srcBlock1) + encrypter.CryptBlocks(encrypted, srcBlock1) if !bytes.Equal([]byte{ 0x14, 0xb7, 0x3e, 0x2f, 0xd9, 0xe7, 0x69, 0x7e, 0xb7, 0xd2, 0xc3, 0x5b, 0x31, 0x9c, 0xf0, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -273,7 +271,7 @@ func TestCBCBlobEncryptBasicBlockEncryption(t *testing.T) { // Second block. 16 bytes. srcBlock2 := bytes.Repeat([]byte{0x02}, 16) - encryptor.CryptBlocks(encrypted[16:], srcBlock2) + encrypter.CryptBlocks(encrypted[16:], srcBlock2) if !bytes.Equal([]byte{ 0x14, 0xb7, 0x3e, 0x2f, 0xd9, 0xe7, 0x69, 0x7e, 0xb7, 0xd2, 0xc3, 0x5b, 0x31, 0x9c, 0xf0, 0x59, 0xbb, 0xd4, 0x95, 0x25, 0x21, 0x56, 0x87, 0x3b, 0xe6, 0x22, 0xe8, 0xd0, 0x19, 0xa8, 0xed, 0xcd, @@ -281,13 +279,7 @@ func TestCBCBlobEncryptBasicBlockEncryption(t *testing.T) { t.Error("unexpected CryptBlocks result for second block") } - var decrypter cipher.BlockMode - if c, ok := block.(*aesCipher); ok { - decrypter = c.NewCBCDecrypter(iv) - if decrypter == nil { - t.Error("unable to create new CBC decrypter") - } - } + decrypter := cipher.NewCBCDecrypter(block, iv) plainText := append(srcBlock1, srcBlock2...) decrypted := make([]byte, len(plainText)) decrypter.CryptBlocks(decrypted, encrypted[:16]) @@ -305,7 +297,7 @@ func TestCBCDecryptSimple(t *testing.T) { 0xe3, 0xbd, 0xa1, 0xc4, 0xbf, 0x61, 0x2f, 0xc5, } - block, err := NewAESCipher(key) + block, err := cng.NewAESCipher(key) if err != nil { t.Fatal(err) } @@ -314,17 +306,9 @@ func TestCBCDecryptSimple(t *testing.T) { 0x91, 0xc7, 0xa7, 0x54, 0x52, 0xef, 0x10, 0xdb, 0x91, 0xa8, 0x6c, 0xf9, 0x79, 0xd5, 0xac, 0x74, } - var encrypter, decrypter cipher.BlockMode - if c, ok := block.(*aesCipher); ok { - encrypter = c.NewCBCEncrypter(iv) - if encrypter == nil { - t.Error("unable to create new CBC encrypter") - } - decrypter = c.NewCBCDecrypter(iv) - if decrypter == nil { - t.Error("unable to create new CBC decrypter") - } - } + + encrypter := cipher.NewCBCEncrypter(block, iv) + decrypter := cipher.NewCBCDecrypter(block, iv) plainText := []byte{ 0x54, 0x68, 0x65, 0x72, 0x65, 0x20, 0x69, 0x73, @@ -386,7 +370,7 @@ func TestCBCDecryptSimple(t *testing.T) { func TestAESBlock(t *testing.T) { for _, keylen := range []int{128, 192, 256} { t.Run(fmt.Sprintf("AES-%d", keylen), func(t *testing.T) { - cryptotest.TestBlock(t, keylen/8, NewAESCipher) + cryptotest.TestBlock(t, keylen/8, cng.NewAESCipher) }) } } @@ -399,7 +383,7 @@ func TestAESBlockMode(t *testing.T) { key := make([]byte, keylen/8) rng.Read(key) - block, err := NewAESCipher(key) + block, err := cng.NewAESCipher(key) if err != nil { t.Fatal(err) } @@ -421,7 +405,7 @@ func TestAESGCMAEAD(t *testing.T) { key := make([]byte, keySize/8) rng.Read(key) - block, err := NewAESCipher(key) + block, err := cng.NewAESCipher(key) if err != nil { panic(err) } @@ -445,9 +429,3 @@ func TestAESGCMAEAD(t *testing.T) { }) } } - -func newRandReader(t *testing.T) io.Reader { - seed := time.Now().UnixNano() - t.Logf("Deterministic RNG seed: 0x%x", seed) - return rand.New(rand.NewSource(seed)) -} diff --git a/cng/cng_test.go b/cng/cng_test.go index bfe0960..c702e9d 100644 --- a/cng/cng_test.go +++ b/cng/cng_test.go @@ -8,9 +8,12 @@ package cng_test import ( "fmt" + "io" + "math/rand" "os" "strconv" "testing" + "time" "github.com/microsoft/go-crypto-winnative/cng" ) @@ -39,3 +42,9 @@ func TestFIPS(t *testing.T) { } } } + +func newRandReader(t *testing.T) io.Reader { + seed := time.Now().UnixNano() + t.Logf("Deterministic RNG seed: 0x%x", seed) + return rand.New(rand.NewSource(seed)) +} diff --git a/cng/hmac_test.go b/cng/hmac_test.go index 713727c..1758a35 100644 --- a/cng/hmac_test.go +++ b/cng/hmac_test.go @@ -4,13 +4,15 @@ //go:build windows // +build windows -package cng +package cng_test import ( "bytes" "fmt" "hash" "testing" + + "github.com/microsoft/go-crypto-winnative/cng" ) func TestHMAC_EmptyKey(t *testing.T) { @@ -20,14 +22,14 @@ func TestHMAC_EmptyKey(t *testing.T) { fn func() hash.Hash out string }{ - {"sha1", NewSHA1, "d5d1ed05121417247616cfc8378f360a39da7cfa"}, - {"sha256", NewSHA256, "eb08c1f56d5ddee07f7bdf80468083da06b64cf4fac64fe3a90883df5feacae4"}, - {"sha384", NewSHA384, "a1302a8028a419bb834bfae53c5e98ab48e07aed9ef8b980a821df28685902003746ade315072edd8ce009a1d23705ec"}, - {"sha512", NewSHA512, "08fce52f6395d59c2a3fb8abb281d74ad6f112b9a9c787bcea290d94dadbc82b2ca3e5e12bf2277c7fedbb0154d5493e41bb7459f63c8e39554ea3651b812492"}, + {"sha1", cng.NewSHA1, "d5d1ed05121417247616cfc8378f360a39da7cfa"}, + {"sha256", cng.NewSHA256, "eb08c1f56d5ddee07f7bdf80468083da06b64cf4fac64fe3a90883df5feacae4"}, + {"sha384", cng.NewSHA384, "a1302a8028a419bb834bfae53c5e98ab48e07aed9ef8b980a821df28685902003746ade315072edd8ce009a1d23705ec"}, + {"sha512", cng.NewSHA512, "08fce52f6395d59c2a3fb8abb281d74ad6f112b9a9c787bcea290d94dadbc82b2ca3e5e12bf2277c7fedbb0154d5493e41bb7459f63c8e39554ea3651b812492"}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - h := NewHMAC(tt.fn, nil) + h := cng.NewHMAC(tt.fn, nil) h.Write([]byte(payload)) sum := fmt.Sprintf("%x", h.Sum(nil)) if sum != tt.out { @@ -44,26 +46,26 @@ func TestHMAC(t *testing.T) { fn func() hash.Hash key []byte }{ - {"sha1", NewSHA1, key}, - {"sha256", NewSHA256, key}, - {"sha256-big", NewSHA256, append(key, make([]byte, 1000)...)}, - {"sha384", NewSHA384, key}, - {"sha512", NewSHA512, key}, + {"sha1", cng.NewSHA1, key}, + {"sha256", cng.NewSHA256, key}, + {"sha256-big", cng.NewSHA256, append(key, make([]byte, 1000)...)}, + {"sha384", cng.NewSHA384, key}, + {"sha512", cng.NewSHA512, key}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - h := NewHMAC(tt.fn, tt.key) + h := cng.NewHMAC(tt.fn, tt.key) h.Write([]byte("hello")) sumHello := h.Sum(nil) - h = NewHMAC(tt.fn, tt.key) + h = cng.NewHMAC(tt.fn, tt.key) h.Write([]byte("hello world")) sumHelloWorld := h.Sum(nil) // Test that Sum has no effect on future Sum or Write operations. // This is a bit unusual as far as usage, but it's allowed // by the definition of Go hash.Hash, and some clients expect it to work. - h = NewHMAC(tt.fn, tt.key) + h = cng.NewHMAC(tt.fn, tt.key) h.Write([]byte("hello")) if sum := h.Sum(nil); !bytes.Equal(sum, sumHello) { t.Fatalf("1st Sum after hello = %x, want %x", sum, sumHello) diff --git a/cng/rand_test.go b/cng/rand_test.go index 80d1758..9654f6e 100644 --- a/cng/rand_test.go +++ b/cng/rand_test.go @@ -4,16 +4,18 @@ //go:build windows // +build windows -package cng +package cng_test import ( "io" "testing" + + "github.com/microsoft/go-crypto-winnative/cng" ) func TestRand(t *testing.T) { b := make([]byte, 5) - n, err := RandReader.Read(b) + n, err := cng.RandReader.Read(b) if err != nil { t.Fatal(err) } @@ -28,7 +30,7 @@ func TestRandBig(t *testing.T) { t.Skip("skipping test in short mode.") } b := make([]byte, 1<<32+60) - n, err := io.ReadFull(RandReader, b) + n, err := io.ReadFull(cng.RandReader, b) if err != nil { t.Fatal(err) }