starcrypto/symm/symm_test.go

609 lines
18 KiB
Go

package symm
import (
"bytes"
"encoding/hex"
"testing"
)
func TestEncryptAesDefaultModeCBC(t *testing.T) {
key := []byte("0123456789abcdef")
iv := []byte("abcdef9876543210")
plain := []byte("aes-default-mode-cbc")
encDefault, err := EncryptAes(plain, key, iv, "", "")
if err != nil {
t.Fatalf("EncryptAes default failed: %v", err)
}
encCBC, err := EncryptAesCBC(plain, key, iv, "")
if err != nil {
t.Fatalf("EncryptAesCBC failed: %v", err)
}
if !bytes.Equal(encDefault, encCBC) {
t.Fatalf("default mode should match CBC mode")
}
}
func TestAESCBCRoundTripDefaultPKCS7(t *testing.T) {
key := []byte("0123456789abcdef")
iv := []byte("abcdef9876543210")
plain := []byte("aes-cbc-with-default-padding")
enc, err := EncryptAesCBC(plain, key, iv, "")
if err != nil {
t.Fatalf("EncryptAesCBC failed: %v", err)
}
dec, err := DecryptAesCBC(enc, key, iv, "")
if err != nil {
t.Fatalf("DecryptAesCBC failed: %v", err)
}
if !bytes.Equal(dec, plain) {
t.Fatalf("aes cbc mismatch, got %q want %q", dec, plain)
}
}
func TestAESCFBRoundTrip(t *testing.T) {
key := []byte("0123456789abcdef")
plain := []byte("aes-cfb-roundtrip")
enc, err := CustomEncryptAesCFB(plain, key)
if err != nil {
t.Fatalf("CustomEncryptAesCFB failed: %v", err)
}
dec, err := CustomDecryptAesCFB(enc, key)
if err != nil {
t.Fatalf("CustomDecryptAesCFB failed: %v", err)
}
if !bytes.Equal(dec, plain) {
t.Fatalf("aes cfb mismatch, got %q want %q", dec, plain)
}
}
func TestAesGenericModesRoundTrip(t *testing.T) {
key := []byte("0123456789abcdef")
iv := []byte("abcdef9876543210")
plain := []byte("generic-aes-mode-roundtrip")
modes := []string{MODEECB, MODECBC, MODECFB, MODEOFB, MODECTR}
for _, mode := range modes {
t.Run(mode, func(t *testing.T) {
useIV := iv
if mode == MODEECB {
useIV = nil
}
enc, err := EncryptAes(plain, key, useIV, mode, "")
if err != nil {
t.Fatalf("EncryptAes(%s) failed: %v", mode, err)
}
dec, err := DecryptAes(enc, key, useIV, mode, "")
if err != nil {
t.Fatalf("DecryptAes(%s) failed: %v", mode, err)
}
if !bytes.Equal(dec, plain) {
t.Fatalf("aes %s mismatch", mode)
}
})
}
}
func TestAesDerivedFunctionsRoundTrip(t *testing.T) {
key := []byte("0123456789abcdef")
iv := []byte("abcdef9876543210")
plain := []byte("aes-derived-func-roundtrip")
ecbEnc, err := EncryptAesECB(plain, key, "")
if err != nil {
t.Fatalf("EncryptAesECB failed: %v", err)
}
ecbDec, err := DecryptAesECB(ecbEnc, key, "")
if err != nil {
t.Fatalf("DecryptAesECB failed: %v", err)
}
if !bytes.Equal(ecbDec, plain) {
t.Fatalf("aes ecb mismatch")
}
cfbEnc, err := EncryptAesCFB(plain, key, iv)
if err != nil {
t.Fatalf("EncryptAesCFB failed: %v", err)
}
cfbDec, err := DecryptAesCFB(cfbEnc, key, iv)
if err != nil {
t.Fatalf("DecryptAesCFB failed: %v", err)
}
if !bytes.Equal(cfbDec, plain) {
t.Fatalf("aes cfb mismatch")
}
ofbEnc, err := EncryptAesOFB(plain, key, iv)
if err != nil {
t.Fatalf("EncryptAesOFB failed: %v", err)
}
ofbDec, err := DecryptAesOFB(ofbEnc, key, iv)
if err != nil {
t.Fatalf("DecryptAesOFB failed: %v", err)
}
if !bytes.Equal(ofbDec, plain) {
t.Fatalf("aes ofb mismatch")
}
ctrEnc, err := EncryptAesCTR(plain, key, iv)
if err != nil {
t.Fatalf("EncryptAesCTR failed: %v", err)
}
ctrDec, err := DecryptAesCTR(ctrEnc, key, iv)
if err != nil {
t.Fatalf("DecryptAesCTR failed: %v", err)
}
if !bytes.Equal(ctrDec, plain) {
t.Fatalf("aes ctr mismatch")
}
}
func TestAesStreamRoundTrip(t *testing.T) {
key := []byte("0123456789abcdef")
iv := []byte("abcdef9876543210")
plain := []byte("streaming-aes-mode-roundtrip-content")
modes := []string{MODEECB, MODECBC, MODECFB, MODEOFB, MODECTR}
for _, mode := range modes {
t.Run(mode, func(t *testing.T) {
encBuf := &bytes.Buffer{}
decBuf := &bytes.Buffer{}
useIV := iv
if mode == MODEECB {
useIV = nil
}
if err := EncryptAesStream(encBuf, bytes.NewReader(plain), key, useIV, mode, ""); err != nil {
t.Fatalf("EncryptAesStream(%s) failed: %v", mode, err)
}
if err := DecryptAesStream(decBuf, bytes.NewReader(encBuf.Bytes()), key, useIV, mode, ""); err != nil {
t.Fatalf("DecryptAesStream(%s) failed: %v", mode, err)
}
if !bytes.Equal(decBuf.Bytes(), plain) {
t.Fatalf("aes stream %s mismatch", mode)
}
})
}
}
func TestAesStreamInvalidMode(t *testing.T) {
key := []byte("0123456789abcdef")
iv := []byte("abcdef9876543210")
err := EncryptAesStream(&bytes.Buffer{}, bytes.NewReader([]byte("x")), key, iv, "BAD", "")
if err == nil {
t.Fatalf("expected invalid mode error")
}
}
func TestSM4CBCRoundTripDefaultPKCS7(t *testing.T) {
key := []byte("0123456789abcdef")
iv := []byte("abcdef9876543210")
plain := []byte("sm4-cbc-with-default-padding")
enc, err := EncryptSM4CBC(plain, key, iv, "")
if err != nil {
t.Fatalf("EncryptSM4CBC failed: %v", err)
}
dec, err := DecryptSM4CBC(enc, key, iv, "")
if err != nil {
t.Fatalf("DecryptSM4CBC failed: %v", err)
}
if !bytes.Equal(dec, plain) {
t.Fatalf("sm4 cbc mismatch, got %q want %q", dec, plain)
}
}
func TestSM4CFBRoundTrip(t *testing.T) {
key := []byte("0123456789abcdef")
plain := []byte("sm4-cfb-roundtrip")
enc, err := EncryptSM4CFB(plain, key)
if err != nil {
t.Fatalf("EncryptSM4CFB failed: %v", err)
}
dec, err := DecryptSM4CFB(enc, key)
if err != nil {
t.Fatalf("DecryptSM4CFB failed: %v", err)
}
if !bytes.Equal(dec, plain) {
t.Fatalf("sm4 cfb mismatch, got %q want %q", dec, plain)
}
}
func TestSM4StreamRoundTrip(t *testing.T) {
key := []byte("0123456789abcdef")
iv := []byte("abcdef9876543210")
plain := []byte("sm4-stream-roundtrip-data")
encCBC := &bytes.Buffer{}
if err := EncryptSM4CBCStream(encCBC, bytes.NewReader(plain), key, iv, ""); err != nil {
t.Fatalf("EncryptSM4CBCStream failed: %v", err)
}
decCBC := &bytes.Buffer{}
if err := DecryptSM4CBCStream(decCBC, bytes.NewReader(encCBC.Bytes()), key, iv, ""); err != nil {
t.Fatalf("DecryptSM4CBCStream failed: %v", err)
}
if !bytes.Equal(decCBC.Bytes(), plain) {
t.Fatalf("sm4 cbc stream mismatch")
}
encCFB := &bytes.Buffer{}
if err := EncryptSM4CFBStream(encCFB, bytes.NewReader(plain), key, iv); err != nil {
t.Fatalf("EncryptSM4CFBStream failed: %v", err)
}
decCFB := &bytes.Buffer{}
if err := DecryptSM4CFBStream(decCFB, bytes.NewReader(encCFB.Bytes()), key, iv); err != nil {
t.Fatalf("DecryptSM4CFBStream failed: %v", err)
}
if !bytes.Equal(decCFB.Bytes(), plain) {
t.Fatalf("sm4 cfb stream mismatch")
}
}
func TestDESCBCRoundTripDefaultPKCS5(t *testing.T) {
key := []byte("12345678")
iv := []byte("abcdefgh")
plain := []byte("des-cbc")
enc, err := EncryptDESCBC(plain, key, iv, "")
if err != nil {
t.Fatalf("EncryptDESCBC failed: %v", err)
}
dec, err := DecryptDESCBC(enc, key, iv, "")
if err != nil {
t.Fatalf("DecryptDESCBC failed: %v", err)
}
if !bytes.Equal(dec, plain) {
t.Fatalf("des cbc mismatch, got %q want %q", dec, plain)
}
}
func Test3DESCBCRoundTripDefaultPKCS5(t *testing.T) {
key := []byte("12345678abcdefgh87654321")
iv := []byte("12345678")
plain := []byte("3des-cbc-default-padding")
enc, err := Encrypt3DESCBC(plain, key, iv, "")
if err != nil {
t.Fatalf("Encrypt3DESCBC failed: %v", err)
}
dec, err := Decrypt3DESCBC(enc, key, iv, "")
if err != nil {
t.Fatalf("Decrypt3DESCBC failed: %v", err)
}
if !bytes.Equal(dec, plain) {
t.Fatalf("3des cbc mismatch, got %q want %q", dec, plain)
}
}
func TestDESStreamRoundTrip(t *testing.T) {
desKey := []byte("12345678")
desIV := []byte("abcdefgh")
desPlain := []byte("des-stream-roundtrip")
desEnc := &bytes.Buffer{}
if err := EncryptDESCBCStream(desEnc, bytes.NewReader(desPlain), desKey, desIV, ""); err != nil {
t.Fatalf("EncryptDESCBCStream failed: %v", err)
}
desDec := &bytes.Buffer{}
if err := DecryptDESCBCStream(desDec, bytes.NewReader(desEnc.Bytes()), desKey, desIV, ""); err != nil {
t.Fatalf("DecryptDESCBCStream failed: %v", err)
}
if !bytes.Equal(desDec.Bytes(), desPlain) {
t.Fatalf("des cbc stream mismatch")
}
key3des := []byte("12345678abcdefgh87654321")
iv3des := []byte("12345678")
plain3des := []byte("3des-stream-roundtrip")
enc3des := &bytes.Buffer{}
if err := Encrypt3DESCBCStream(enc3des, bytes.NewReader(plain3des), key3des, iv3des, ""); err != nil {
t.Fatalf("Encrypt3DESCBCStream failed: %v", err)
}
dec3des := &bytes.Buffer{}
if err := Decrypt3DESCBCStream(dec3des, bytes.NewReader(enc3des.Bytes()), key3des, iv3des, ""); err != nil {
t.Fatalf("Decrypt3DESCBCStream failed: %v", err)
}
if !bytes.Equal(dec3des.Bytes(), plain3des) {
t.Fatalf("3des cbc stream mismatch")
}
}
func TestCBCInvalidIVLength(t *testing.T) {
_, err := EncryptAesCBC([]byte("a"), []byte("0123456789abcdef"), []byte("short"), PKCS7PADDING)
if err == nil {
t.Fatalf("expected invalid IV length error")
}
}
func TestCBCInvalidCiphertextLength(t *testing.T) {
_, err := DecryptSM4CBC([]byte("short"), []byte("0123456789abcdef"), []byte("abcdef9876543210"), PKCS7PADDING)
if err == nil {
t.Fatalf("expected invalid ciphertext length error")
}
}
func TestCBCStreamInvalidCiphertextLength(t *testing.T) {
err := DecryptAesCBCStream(&bytes.Buffer{}, bytes.NewReader([]byte("short")), []byte("0123456789abcdef"), []byte("abcdef9876543210"), PKCS7PADDING)
if err == nil {
t.Fatalf("expected invalid ciphertext length error")
}
}
func TestSM4DerivedModesRoundTrip(t *testing.T) {
key := []byte("0123456789abcdef")
iv := []byte("abcdef9876543210")
plain := []byte("sm4-derived-mode-roundtrip")
ecbEnc, err := EncryptSM4ECB(plain, key, "")
if err != nil {
t.Fatalf("EncryptSM4ECB failed: %v", err)
}
ecbDec, err := DecryptSM4ECB(ecbEnc, key, "")
if err != nil {
t.Fatalf("DecryptSM4ECB failed: %v", err)
}
if !bytes.Equal(ecbDec, plain) {
t.Fatalf("sm4 ecb mismatch")
}
ofbEnc, err := EncryptSM4OFB(plain, key, iv)
if err != nil {
t.Fatalf("EncryptSM4OFB failed: %v", err)
}
ofbDec, err := DecryptSM4OFB(ofbEnc, key, iv)
if err != nil {
t.Fatalf("DecryptSM4OFB failed: %v", err)
}
if !bytes.Equal(ofbDec, plain) {
t.Fatalf("sm4 ofb mismatch")
}
ctrEnc, err := EncryptSM4CTR(plain, key, iv)
if err != nil {
t.Fatalf("EncryptSM4CTR failed: %v", err)
}
ctrDec, err := DecryptSM4CTR(ctrEnc, key, iv)
if err != nil {
t.Fatalf("DecryptSM4CTR failed: %v", err)
}
if !bytes.Equal(ctrDec, plain) {
t.Fatalf("sm4 ctr mismatch")
}
}
func TestSM4DerivedStreamRoundTrip(t *testing.T) {
key := []byte("0123456789abcdef")
iv := []byte("abcdef9876543210")
plain := []byte("sm4-derived-stream-roundtrip")
ecbEnc := &bytes.Buffer{}
if err := EncryptSM4ECBStream(ecbEnc, bytes.NewReader(plain), key, ""); err != nil {
t.Fatalf("EncryptSM4ECBStream failed: %v", err)
}
ecbDec := &bytes.Buffer{}
if err := DecryptSM4ECBStream(ecbDec, bytes.NewReader(ecbEnc.Bytes()), key, ""); err != nil {
t.Fatalf("DecryptSM4ECBStream failed: %v", err)
}
if !bytes.Equal(ecbDec.Bytes(), plain) {
t.Fatalf("sm4 ecb stream mismatch")
}
ofbEnc := &bytes.Buffer{}
if err := EncryptSM4OFBStream(ofbEnc, bytes.NewReader(plain), key, iv); err != nil {
t.Fatalf("EncryptSM4OFBStream failed: %v", err)
}
ofbDec := &bytes.Buffer{}
if err := DecryptSM4OFBStream(ofbDec, bytes.NewReader(ofbEnc.Bytes()), key, iv); err != nil {
t.Fatalf("DecryptSM4OFBStream failed: %v", err)
}
if !bytes.Equal(ofbDec.Bytes(), plain) {
t.Fatalf("sm4 ofb stream mismatch")
}
ctrEnc := &bytes.Buffer{}
if err := EncryptSM4CTRStream(ctrEnc, bytes.NewReader(plain), key, iv); err != nil {
t.Fatalf("EncryptSM4CTRStream failed: %v", err)
}
ctrDec := &bytes.Buffer{}
if err := DecryptSM4CTRStream(ctrDec, bytes.NewReader(ctrEnc.Bytes()), key, iv); err != nil {
t.Fatalf("DecryptSM4CTRStream failed: %v", err)
}
if !bytes.Equal(ctrDec.Bytes(), plain) {
t.Fatalf("sm4 ctr stream mismatch")
}
}
func TestChaCha20RoundTrip(t *testing.T) {
key := []byte("0123456789abcdef0123456789abcdef")
nonce := []byte("123456789012")
plain := []byte("chacha20-roundtrip")
enc, err := EncryptChaCha20(plain, key, nonce)
if err != nil {
t.Fatalf("EncryptChaCha20 failed: %v", err)
}
dec, err := DecryptChaCha20(enc, key, nonce)
if err != nil {
t.Fatalf("DecryptChaCha20 failed: %v", err)
}
if !bytes.Equal(dec, plain) {
t.Fatalf("chacha20 mismatch")
}
}
func TestChaCha20StreamRoundTrip(t *testing.T) {
key := []byte("0123456789abcdef0123456789abcdef")
nonce := []byte("123456789012")
plain := []byte("chacha20-stream-roundtrip")
enc := &bytes.Buffer{}
if err := EncryptChaCha20Stream(enc, bytes.NewReader(plain), key, nonce); err != nil {
t.Fatalf("EncryptChaCha20Stream failed: %v", err)
}
dec := &bytes.Buffer{}
if err := DecryptChaCha20Stream(dec, bytes.NewReader(enc.Bytes()), key, nonce); err != nil {
t.Fatalf("DecryptChaCha20Stream failed: %v", err)
}
if !bytes.Equal(dec.Bytes(), plain) {
t.Fatalf("chacha20 stream mismatch")
}
}
func TestChaCha20Poly1305RoundTrip(t *testing.T) {
key := []byte("0123456789abcdef0123456789abcdef")
nonce := []byte("123456789012")
aad := []byte("aad")
plain := []byte("chacha20-poly1305-roundtrip")
enc, err := EncryptChaCha20Poly1305(plain, key, nonce, aad)
if err != nil {
t.Fatalf("EncryptChaCha20Poly1305 failed: %v", err)
}
dec, err := DecryptChaCha20Poly1305(enc, key, nonce, aad)
if err != nil {
t.Fatalf("DecryptChaCha20Poly1305 failed: %v", err)
}
if !bytes.Equal(dec, plain) {
t.Fatalf("chacha20-poly1305 mismatch")
}
}
func TestChaCha20Poly1305InvalidNonce(t *testing.T) {
key := []byte("0123456789abcdef0123456789abcdef")
_, err := EncryptChaCha20Poly1305([]byte("x"), key, []byte("short"), nil)
if err == nil {
t.Fatalf("expected invalid nonce error")
}
}
func TestAESGCMNISTVectorEmpty(t *testing.T) {
key := mustHex(t, "00000000000000000000000000000000")
nonce := mustHex(t, "000000000000000000000000")
enc, err := EncryptAesGCM(nil, key, nonce, nil)
if err != nil {
t.Fatalf("EncryptAesGCM failed: %v", err)
}
want := mustHex(t, "58e2fccefa7e3061367f1d57a4e7455a")
if !bytes.Equal(enc, want) {
t.Fatalf("AES-GCM empty vector mismatch: got %x want %x", enc, want)
}
}
func TestAESGCMNISTVectorOneBlock(t *testing.T) {
key := mustHex(t, "00000000000000000000000000000000")
nonce := mustHex(t, "000000000000000000000000")
plain := mustHex(t, "00000000000000000000000000000000")
enc, err := EncryptAesGCM(plain, key, nonce, nil)
if err != nil {
t.Fatalf("EncryptAesGCM failed: %v", err)
}
want := mustHex(t, "0388dace60b6a392f328c2b971b2fe78ab6e47d42cec13bdf53a67b21257bddf")
if !bytes.Equal(enc, want) {
t.Fatalf("AES-GCM one-block vector mismatch: got %x want %x", enc, want)
}
}
func TestSM4ECBStandardVector(t *testing.T) {
key := mustHex(t, "0123456789abcdeffedcba9876543210")
plain := mustHex(t, "0123456789abcdeffedcba9876543210")
enc, err := EncryptSM4ECB(plain, key, ZEROPADDING)
if err != nil {
t.Fatalf("EncryptSM4ECB failed: %v", err)
}
want := mustHex(t, "681edf34d206965e86b3e94f536e4246")
if !bytes.Equal(enc, want) {
t.Fatalf("SM4 ECB vector mismatch: got %x want %x", enc, want)
}
}
func TestChaCha20Poly1305RFCVector(t *testing.T) {
key := mustHex(t, "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f")
nonce := mustHex(t, "070000004041424344454647")
enc, err := EncryptChaCha20Poly1305(nil, key, nonce, nil)
if err != nil {
t.Fatalf("EncryptChaCha20Poly1305 failed: %v", err)
}
want := mustHex(t, "a0784d7a4716f3feb4f64e7f4b39bf04")
if !bytes.Equal(enc, want) {
t.Fatalf("ChaCha20-Poly1305 vector mismatch: got %x want %x", enc, want)
}
}
func TestAesOptionsDefaultToGCM(t *testing.T) {
key := []byte("0123456789abcdef")
nonce := []byte("123456789012")
plain := []byte("aes-options-default-gcm")
enc, err := EncryptAesWithOptions(plain, key, &CipherOptions{Nonce: nonce})
if err != nil {
t.Fatalf("EncryptAesWithOptions failed: %v", err)
}
dec, err := DecryptAesWithOptions(enc, key, &CipherOptions{Nonce: nonce})
if err != nil {
t.Fatalf("DecryptAesWithOptions failed: %v", err)
}
if !bytes.Equal(dec, plain) {
t.Fatalf("aes options default gcm mismatch")
}
}
func TestSM4OptionsDefaultToGCM(t *testing.T) {
key := []byte("0123456789abcdef")
nonce := []byte("123456789012")
plain := []byte("sm4-options-default-gcm")
enc, err := EncryptSM4WithOptions(plain, key, &CipherOptions{Nonce: nonce})
if err != nil {
t.Fatalf("EncryptSM4WithOptions failed: %v", err)
}
dec, err := DecryptSM4WithOptions(enc, key, &CipherOptions{Nonce: nonce})
if err != nil {
t.Fatalf("DecryptSM4WithOptions failed: %v", err)
}
if !bytes.Equal(dec, plain) {
t.Fatalf("sm4 options default gcm mismatch")
}
}
func TestLargeStreamRoundTrip(t *testing.T) {
large := bytes.Repeat([]byte("starcrypto-large-stream-data-0123456789"), 180000)
aesKey := []byte("0123456789abcdef")
aesIV := []byte("abcdef9876543210")
aesEnc := &bytes.Buffer{}
if err := EncryptAesCBCStream(aesEnc, bytes.NewReader(large), aesKey, aesIV, ""); err != nil {
t.Fatalf("EncryptAesCBCStream large failed: %v", err)
}
aesDec := &bytes.Buffer{}
if err := DecryptAesCBCStream(aesDec, bytes.NewReader(aesEnc.Bytes()), aesKey, aesIV, ""); err != nil {
t.Fatalf("DecryptAesCBCStream large failed: %v", err)
}
if !bytes.Equal(aesDec.Bytes(), large) {
t.Fatalf("aes large stream mismatch")
}
chachaKey := []byte("0123456789abcdef0123456789abcdef")
chachaNonce := []byte("123456789012")
chachaEnc := &bytes.Buffer{}
if err := EncryptChaCha20Stream(chachaEnc, bytes.NewReader(large), chachaKey, chachaNonce); err != nil {
t.Fatalf("EncryptChaCha20Stream large failed: %v", err)
}
chachaDec := &bytes.Buffer{}
if err := DecryptChaCha20Stream(chachaDec, bytes.NewReader(chachaEnc.Bytes()), chachaKey, chachaNonce); err != nil {
t.Fatalf("DecryptChaCha20Stream large failed: %v", err)
}
if !bytes.Equal(chachaDec.Bytes(), large) {
t.Fatalf("chacha20 large stream mismatch")
}
}
func mustHex(t *testing.T, s string) []byte {
t.Helper()
b, err := hex.DecodeString(s)
if err != nil {
t.Fatalf("DecodeString failed: %v", err)
}
return b
}