Skip to content

Commit

Permalink
Merge pull request #66 from microsoft/dev/qmuntal/aesbbox
Browse files Browse the repository at this point in the history
Use black box testing in all test files
  • Loading branch information
karianna authored Sep 27, 2024
2 parents 21c2e67 + 46549d6 commit c3f8deb
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 76 deletions.
96 changes: 37 additions & 59 deletions cng/aes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand All @@ -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)
}
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
}
Expand All @@ -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)
}
}
Expand All @@ -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)
}
Expand All @@ -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)
}
Expand All @@ -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)
}
Expand All @@ -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,
Expand All @@ -273,21 +271,15 @@ 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,
}, encrypted) {
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])
Expand All @@ -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)
}
Expand All @@ -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,
Expand Down Expand Up @@ -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)
})
}
}
Expand All @@ -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)
}
Expand All @@ -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)
}
Expand All @@ -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))
}
9 changes: 9 additions & 0 deletions cng/cng_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,12 @@ package cng_test

import (
"fmt"
"io"
"math/rand"
"os"
"strconv"
"testing"
"time"

"github.com/microsoft/go-crypto-winnative/cng"
)
Expand Down Expand Up @@ -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))
}
30 changes: 16 additions & 14 deletions cng/hmac_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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 {
Expand All @@ -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)
Expand Down
8 changes: 5 additions & 3 deletions cng/rand_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand All @@ -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)
}
Expand Down

0 comments on commit c3f8deb

Please sign in to comment.