1340 lines
39 KiB
Go
1340 lines
39 KiB
Go
package symm
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/hex"
|
|
"testing"
|
|
)
|
|
|
|
func TestEncryptAesDefaultModeGCM(t *testing.T) {
|
|
key := []byte("0123456789abcdef")
|
|
nonce := []byte("123456789012")
|
|
plain := []byte("aes-default-mode-gcm")
|
|
|
|
encDefault, err := EncryptAes(plain, key, nonce, "", "")
|
|
if err != nil {
|
|
t.Fatalf("EncryptAes default failed: %v", err)
|
|
}
|
|
encGCM, err := EncryptAesGCM(plain, key, nonce, nil)
|
|
if err != nil {
|
|
t.Fatalf("EncryptAesGCM failed: %v", err)
|
|
}
|
|
if !bytes.Equal(encDefault, encGCM) {
|
|
t.Fatalf("default mode should match GCM mode")
|
|
}
|
|
}
|
|
|
|
func TestEncryptSM4DefaultModeGCM(t *testing.T) {
|
|
key := []byte("0123456789abcdef")
|
|
nonce := []byte("123456789012")
|
|
plain := []byte("sm4-default-mode-gcm")
|
|
|
|
encDefault, err := EncryptSM4(plain, key, nonce, "", "")
|
|
if err != nil {
|
|
t.Fatalf("EncryptSM4 default failed: %v", err)
|
|
}
|
|
encGCM, err := EncryptSM4GCM(plain, key, nonce, nil)
|
|
if err != nil {
|
|
t.Fatalf("EncryptSM4GCM failed: %v", err)
|
|
}
|
|
if !bytes.Equal(encDefault, encGCM) {
|
|
t.Fatalf("default mode should match GCM 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 TestAesGCMStreamRoundTripChunked(t *testing.T) {
|
|
key := []byte("0123456789abcdef")
|
|
nonce := []byte("123456789012")
|
|
aad := []byte("aad")
|
|
plain := bytes.Repeat([]byte("aes-gcm-stream-chunk-"), 10000)
|
|
|
|
enc := &bytes.Buffer{}
|
|
if err := EncryptAesGCMStream(enc, bytes.NewReader(plain), key, nonce, aad); err != nil {
|
|
t.Fatalf("EncryptAesGCMStream failed: %v", err)
|
|
}
|
|
dec := &bytes.Buffer{}
|
|
if err := DecryptAesGCMStream(dec, bytes.NewReader(enc.Bytes()), key, nonce, aad); err != nil {
|
|
t.Fatalf("DecryptAesGCMStream failed: %v", err)
|
|
}
|
|
if !bytes.Equal(dec.Bytes(), plain) {
|
|
t.Fatalf("aes gcm stream mismatch")
|
|
}
|
|
}
|
|
|
|
func TestAesGCMStreamLegacyCompatDecrypt(t *testing.T) {
|
|
key := []byte("0123456789abcdef")
|
|
nonce := []byte("123456789012")
|
|
aad := []byte("aad")
|
|
plain := []byte("aes-gcm-legacy-compat")
|
|
|
|
legacyCipher, err := EncryptAesGCM(plain, key, nonce, aad)
|
|
if err != nil {
|
|
t.Fatalf("EncryptAesGCM failed: %v", err)
|
|
}
|
|
dec := &bytes.Buffer{}
|
|
if err := DecryptAesGCMStream(dec, bytes.NewReader(legacyCipher), key, nonce, aad); err != nil {
|
|
t.Fatalf("DecryptAesGCMStream failed: %v", err)
|
|
}
|
|
if !bytes.Equal(dec.Bytes(), plain) {
|
|
t.Fatalf("aes gcm legacy decrypt mismatch")
|
|
}
|
|
}
|
|
|
|
func TestSM4GCMStreamRoundTripChunked(t *testing.T) {
|
|
key := []byte("0123456789abcdef")
|
|
nonce := []byte("123456789012")
|
|
aad := []byte("aad")
|
|
plain := bytes.Repeat([]byte("sm4-gcm-stream-chunk-"), 10000)
|
|
|
|
enc := &bytes.Buffer{}
|
|
if err := EncryptSM4GCMStream(enc, bytes.NewReader(plain), key, nonce, aad); err != nil {
|
|
t.Fatalf("EncryptSM4GCMStream failed: %v", err)
|
|
}
|
|
dec := &bytes.Buffer{}
|
|
if err := DecryptSM4GCMStream(dec, bytes.NewReader(enc.Bytes()), key, nonce, aad); err != nil {
|
|
t.Fatalf("DecryptSM4GCMStream failed: %v", err)
|
|
}
|
|
if !bytes.Equal(dec.Bytes(), plain) {
|
|
t.Fatalf("sm4 gcm stream mismatch")
|
|
}
|
|
}
|
|
|
|
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 TestAesCTRAtOffsetSegment(t *testing.T) {
|
|
key := []byte("0123456789abcdef")
|
|
iv := []byte("abcdef9876543210")
|
|
plain := bytes.Repeat([]byte("aes-ctr-offset-"), 256)
|
|
|
|
full, err := EncryptAesCTR(plain, key, iv)
|
|
if err != nil {
|
|
t.Fatalf("EncryptAesCTR failed: %v", err)
|
|
}
|
|
|
|
offset := 137
|
|
length := 521
|
|
segCipher := full[offset : offset+length]
|
|
|
|
segPlain, err := DecryptAesCTRAt(segCipher, key, iv, int64(offset))
|
|
if err != nil {
|
|
t.Fatalf("DecryptAesCTRAt failed: %v", err)
|
|
}
|
|
if !bytes.Equal(segPlain, plain[offset:offset+length]) {
|
|
t.Fatalf("aes ctr offset decrypt mismatch")
|
|
}
|
|
|
|
encSeg, err := EncryptAesCTRAt(plain[offset:offset+length], key, iv, int64(offset))
|
|
if err != nil {
|
|
t.Fatalf("EncryptAesCTRAt failed: %v", err)
|
|
}
|
|
if !bytes.Equal(encSeg, segCipher) {
|
|
t.Fatalf("aes ctr offset encrypt mismatch")
|
|
}
|
|
}
|
|
|
|
func TestSM4CTRAtOffsetSegment(t *testing.T) {
|
|
key := []byte("0123456789abcdef")
|
|
iv := []byte("abcdef9876543210")
|
|
plain := bytes.Repeat([]byte("sm4-ctr-offset-"), 256)
|
|
|
|
full, err := EncryptSM4CTR(plain, key, iv)
|
|
if err != nil {
|
|
t.Fatalf("EncryptSM4CTR failed: %v", err)
|
|
}
|
|
|
|
offset := 193
|
|
length := 487
|
|
segCipher := full[offset : offset+length]
|
|
|
|
segPlain, err := DecryptSM4CTRAt(segCipher, key, iv, int64(offset))
|
|
if err != nil {
|
|
t.Fatalf("DecryptSM4CTRAt failed: %v", err)
|
|
}
|
|
if !bytes.Equal(segPlain, plain[offset:offset+length]) {
|
|
t.Fatalf("sm4 ctr offset decrypt mismatch")
|
|
}
|
|
|
|
encSeg, err := EncryptSM4CTRAt(plain[offset:offset+length], key, iv, int64(offset))
|
|
if err != nil {
|
|
t.Fatalf("EncryptSM4CTRAt failed: %v", err)
|
|
}
|
|
if !bytes.Equal(encSeg, segCipher) {
|
|
t.Fatalf("sm4 ctr offset encrypt mismatch")
|
|
}
|
|
}
|
|
|
|
func TestAesGCMChunkRoundTrip(t *testing.T) {
|
|
key := []byte("0123456789abcdef")
|
|
nonce := []byte("123456789012")
|
|
aad := []byte("aad")
|
|
plain := []byte("aes-gcm-chunk")
|
|
chunkIndex := uint64(7)
|
|
|
|
enc, err := EncryptAesGCMChunk(plain, key, nonce, aad, chunkIndex)
|
|
if err != nil {
|
|
t.Fatalf("EncryptAesGCMChunk failed: %v", err)
|
|
}
|
|
dec, err := DecryptAesGCMChunk(enc, key, nonce, aad, chunkIndex)
|
|
if err != nil {
|
|
t.Fatalf("DecryptAesGCMChunk failed: %v", err)
|
|
}
|
|
if !bytes.Equal(dec, plain) {
|
|
t.Fatalf("aes gcm chunk decrypt mismatch")
|
|
}
|
|
if _, err := DecryptAesGCMChunk(enc, key, nonce, aad, chunkIndex+1); err == nil {
|
|
t.Fatalf("expected decrypt error for wrong chunk index")
|
|
}
|
|
}
|
|
|
|
func TestSM4GCMChunkRoundTrip(t *testing.T) {
|
|
key := []byte("0123456789abcdef")
|
|
nonce := []byte("123456789012")
|
|
aad := []byte("aad")
|
|
plain := []byte("sm4-gcm-chunk")
|
|
chunkIndex := uint64(11)
|
|
|
|
enc, err := EncryptSM4GCMChunk(plain, key, nonce, aad, chunkIndex)
|
|
if err != nil {
|
|
t.Fatalf("EncryptSM4GCMChunk failed: %v", err)
|
|
}
|
|
dec, err := DecryptSM4GCMChunk(enc, key, nonce, aad, chunkIndex)
|
|
if err != nil {
|
|
t.Fatalf("DecryptSM4GCMChunk failed: %v", err)
|
|
}
|
|
if !bytes.Equal(dec, plain) {
|
|
t.Fatalf("sm4 gcm chunk decrypt mismatch")
|
|
}
|
|
if _, err := DecryptSM4GCMChunk(enc, key, nonce, aad, chunkIndex+1); err == nil {
|
|
t.Fatalf("expected decrypt error for wrong chunk index")
|
|
}
|
|
}
|
|
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
|
|
}
|
|
|
|
func TestAesCFB8RoundTrip(t *testing.T) {
|
|
key := []byte("0123456789abcdef")
|
|
iv := []byte("abcdef9876543210")
|
|
plain := []byte("aes-cfb8-roundtrip-content")
|
|
|
|
enc, err := EncryptAesCFB8(plain, key, iv)
|
|
if err != nil {
|
|
t.Fatalf("EncryptAesCFB8 failed: %v", err)
|
|
}
|
|
dec, err := DecryptAesCFB8(enc, key, iv)
|
|
if err != nil {
|
|
t.Fatalf("DecryptAesCFB8 failed: %v", err)
|
|
}
|
|
if !bytes.Equal(dec, plain) {
|
|
t.Fatalf("aes cfb8 mismatch")
|
|
}
|
|
}
|
|
|
|
func TestSM4CFB8RoundTrip(t *testing.T) {
|
|
key := []byte("0123456789abcdef")
|
|
iv := []byte("abcdef9876543210")
|
|
plain := []byte("sm4-cfb8-roundtrip-content")
|
|
|
|
enc, err := EncryptSM4CFB8(plain, key, iv)
|
|
if err != nil {
|
|
t.Fatalf("EncryptSM4CFB8 failed: %v", err)
|
|
}
|
|
dec, err := DecryptSM4CFB8(enc, key, iv)
|
|
if err != nil {
|
|
t.Fatalf("DecryptSM4CFB8 failed: %v", err)
|
|
}
|
|
if !bytes.Equal(dec, plain) {
|
|
t.Fatalf("sm4 cfb8 mismatch")
|
|
}
|
|
}
|
|
|
|
func TestAesCFB8StreamRoundTrip(t *testing.T) {
|
|
key := []byte("0123456789abcdef")
|
|
iv := []byte("abcdef9876543210")
|
|
plain := bytes.Repeat([]byte("aes-cfb8-stream-"), 512)
|
|
|
|
enc := &bytes.Buffer{}
|
|
if err := EncryptAesCFB8Stream(enc, bytes.NewReader(plain), key, iv); err != nil {
|
|
t.Fatalf("EncryptAesCFB8Stream failed: %v", err)
|
|
}
|
|
dec := &bytes.Buffer{}
|
|
if err := DecryptAesCFB8Stream(dec, bytes.NewReader(enc.Bytes()), key, iv); err != nil {
|
|
t.Fatalf("DecryptAesCFB8Stream failed: %v", err)
|
|
}
|
|
if !bytes.Equal(dec.Bytes(), plain) {
|
|
t.Fatalf("aes cfb8 stream mismatch")
|
|
}
|
|
}
|
|
|
|
func TestSM4CFB8StreamRoundTrip(t *testing.T) {
|
|
key := []byte("0123456789abcdef")
|
|
iv := []byte("abcdef9876543210")
|
|
plain := bytes.Repeat([]byte("sm4-cfb8-stream-"), 512)
|
|
|
|
enc := &bytes.Buffer{}
|
|
if err := EncryptSM4CFB8Stream(enc, bytes.NewReader(plain), key, iv); err != nil {
|
|
t.Fatalf("EncryptSM4CFB8Stream failed: %v", err)
|
|
}
|
|
dec := &bytes.Buffer{}
|
|
if err := DecryptSM4CFB8Stream(dec, bytes.NewReader(enc.Bytes()), key, iv); err != nil {
|
|
t.Fatalf("DecryptSM4CFB8Stream failed: %v", err)
|
|
}
|
|
if !bytes.Equal(dec.Bytes(), plain) {
|
|
t.Fatalf("sm4 cfb8 stream mismatch")
|
|
}
|
|
}
|
|
|
|
func TestAesSegmentDecryptModes(t *testing.T) {
|
|
key := []byte("0123456789abcdef")
|
|
iv := []byte("abcdef9876543210")
|
|
plain := bytes.Repeat([]byte("0123456789abcdef"), 4)
|
|
|
|
ecbEnc, err := EncryptAesECB(plain, key, ZEROPADDING)
|
|
if err != nil {
|
|
t.Fatalf("EncryptAesECB failed: %v", err)
|
|
}
|
|
ecbDec, err := DecryptAesECBBlocks(ecbEnc, key)
|
|
if err != nil {
|
|
t.Fatalf("DecryptAesECBBlocks failed: %v", err)
|
|
}
|
|
if !bytes.Equal(ecbDec, plain) {
|
|
t.Fatalf("aes ecb segment mismatch")
|
|
}
|
|
|
|
cbcEnc, err := EncryptAesCBC(plain, key, iv, ZEROPADDING)
|
|
if err != nil {
|
|
t.Fatalf("EncryptAesCBC failed: %v", err)
|
|
}
|
|
cbcSegDec, err := DecryptAesCBCFromSecondBlock(cbcEnc[len(iv):], key, cbcEnc[:len(iv)])
|
|
if err != nil {
|
|
t.Fatalf("DecryptAesCBCFromSecondBlock failed: %v", err)
|
|
}
|
|
if !bytes.Equal(cbcSegDec, plain[len(iv):]) {
|
|
t.Fatalf("aes cbc from-second-block mismatch")
|
|
}
|
|
|
|
cfbEnc, err := EncryptAesCFB(plain, key, iv)
|
|
if err != nil {
|
|
t.Fatalf("EncryptAesCFB failed: %v", err)
|
|
}
|
|
cfbSegDec, err := DecryptAesCFBFromSecondBlock(cfbEnc[len(iv):], key, cfbEnc[:len(iv)])
|
|
if err != nil {
|
|
t.Fatalf("DecryptAesCFBFromSecondBlock failed: %v", err)
|
|
}
|
|
if !bytes.Equal(cfbSegDec, plain[len(iv):]) {
|
|
t.Fatalf("aes cfb from-second-block mismatch")
|
|
}
|
|
}
|
|
|
|
func TestSM4SegmentDecryptModes(t *testing.T) {
|
|
key := []byte("0123456789abcdef")
|
|
iv := []byte("abcdef9876543210")
|
|
plain := bytes.Repeat([]byte("0123456789abcdef"), 4)
|
|
|
|
ecbEnc, err := EncryptSM4ECB(plain, key, ZEROPADDING)
|
|
if err != nil {
|
|
t.Fatalf("EncryptSM4ECB failed: %v", err)
|
|
}
|
|
ecbDec, err := DecryptSM4ECBBlocks(ecbEnc, key)
|
|
if err != nil {
|
|
t.Fatalf("DecryptSM4ECBBlocks failed: %v", err)
|
|
}
|
|
if !bytes.Equal(ecbDec, plain) {
|
|
t.Fatalf("sm4 ecb segment mismatch")
|
|
}
|
|
|
|
cbcEnc, err := EncryptSM4CBC(plain, key, iv, ZEROPADDING)
|
|
if err != nil {
|
|
t.Fatalf("EncryptSM4CBC failed: %v", err)
|
|
}
|
|
cbcSegDec, err := DecryptSM4CBCFromSecondBlock(cbcEnc[len(iv):], key, cbcEnc[:len(iv)])
|
|
if err != nil {
|
|
t.Fatalf("DecryptSM4CBCFromSecondBlock failed: %v", err)
|
|
}
|
|
if !bytes.Equal(cbcSegDec, plain[len(iv):]) {
|
|
t.Fatalf("sm4 cbc from-second-block mismatch")
|
|
}
|
|
|
|
cfbEnc, err := EncryptSM4CFBNoBlock(plain, key, iv)
|
|
if err != nil {
|
|
t.Fatalf("EncryptSM4CFB failed: %v", err)
|
|
}
|
|
cfbSegDec, err := DecryptSM4CFBFromSecondBlock(cfbEnc[len(iv):], key, cfbEnc[:len(iv)])
|
|
if err != nil {
|
|
t.Fatalf("DecryptSM4CFBFromSecondBlock failed: %v", err)
|
|
}
|
|
if !bytes.Equal(cfbSegDec, plain[len(iv):]) {
|
|
t.Fatalf("sm4 cfb from-second-block mismatch")
|
|
}
|
|
}
|
|
func TestAesCCMRoundTrip(t *testing.T) {
|
|
key := []byte("0123456789abcdef")
|
|
nonce := []byte("123456789012")
|
|
aad := []byte("aad")
|
|
plain := []byte("aes-ccm-roundtrip")
|
|
|
|
enc, err := EncryptAesCCM(plain, key, nonce, aad)
|
|
if err != nil {
|
|
t.Fatalf("EncryptAesCCM failed: %v", err)
|
|
}
|
|
dec, err := DecryptAesCCM(enc, key, nonce, aad)
|
|
if err != nil {
|
|
t.Fatalf("DecryptAesCCM failed: %v", err)
|
|
}
|
|
if !bytes.Equal(dec, plain) {
|
|
t.Fatalf("aes ccm mismatch")
|
|
}
|
|
}
|
|
|
|
func TestSM4CCMRoundTrip(t *testing.T) {
|
|
key := []byte("0123456789abcdef")
|
|
nonce := []byte("123456789012")
|
|
aad := []byte("aad")
|
|
plain := []byte("sm4-ccm-roundtrip")
|
|
|
|
enc, err := EncryptSM4CCM(plain, key, nonce, aad)
|
|
if err != nil {
|
|
t.Fatalf("EncryptSM4CCM failed: %v", err)
|
|
}
|
|
dec, err := DecryptSM4CCM(enc, key, nonce, aad)
|
|
if err != nil {
|
|
t.Fatalf("DecryptSM4CCM failed: %v", err)
|
|
}
|
|
if !bytes.Equal(dec, plain) {
|
|
t.Fatalf("sm4 ccm mismatch")
|
|
}
|
|
}
|
|
|
|
func TestAesCCMStreamRoundTripChunked(t *testing.T) {
|
|
key := []byte("0123456789abcdef")
|
|
nonce := []byte("123456789012")
|
|
aad := []byte("aad")
|
|
plain := bytes.Repeat([]byte("aes-ccm-stream-chunk-"), 10000)
|
|
|
|
enc := &bytes.Buffer{}
|
|
if err := EncryptAesCCMStream(enc, bytes.NewReader(plain), key, nonce, aad); err != nil {
|
|
t.Fatalf("EncryptAesCCMStream failed: %v", err)
|
|
}
|
|
dec := &bytes.Buffer{}
|
|
if err := DecryptAesCCMStream(dec, bytes.NewReader(enc.Bytes()), key, nonce, aad); err != nil {
|
|
t.Fatalf("DecryptAesCCMStream failed: %v", err)
|
|
}
|
|
if !bytes.Equal(dec.Bytes(), plain) {
|
|
t.Fatalf("aes ccm stream mismatch")
|
|
}
|
|
}
|
|
|
|
func TestAesCCMStreamLegacyCompatDecrypt(t *testing.T) {
|
|
key := []byte("0123456789abcdef")
|
|
nonce := []byte("123456789012")
|
|
aad := []byte("aad")
|
|
plain := []byte("aes-ccm-legacy-compat")
|
|
|
|
legacyCipher, err := EncryptAesCCM(plain, key, nonce, aad)
|
|
if err != nil {
|
|
t.Fatalf("EncryptAesCCM failed: %v", err)
|
|
}
|
|
dec := &bytes.Buffer{}
|
|
if err := DecryptAesCCMStream(dec, bytes.NewReader(legacyCipher), key, nonce, aad); err != nil {
|
|
t.Fatalf("DecryptAesCCMStream failed: %v", err)
|
|
}
|
|
if !bytes.Equal(dec.Bytes(), plain) {
|
|
t.Fatalf("aes ccm legacy decrypt mismatch")
|
|
}
|
|
}
|
|
|
|
func TestSM4CCMStreamRoundTripChunked(t *testing.T) {
|
|
key := []byte("0123456789abcdef")
|
|
nonce := []byte("123456789012")
|
|
aad := []byte("aad")
|
|
plain := bytes.Repeat([]byte("sm4-ccm-stream-chunk-"), 10000)
|
|
|
|
enc := &bytes.Buffer{}
|
|
if err := EncryptSM4CCMStream(enc, bytes.NewReader(plain), key, nonce, aad); err != nil {
|
|
t.Fatalf("EncryptSM4CCMStream failed: %v", err)
|
|
}
|
|
dec := &bytes.Buffer{}
|
|
if err := DecryptSM4CCMStream(dec, bytes.NewReader(enc.Bytes()), key, nonce, aad); err != nil {
|
|
t.Fatalf("DecryptSM4CCMStream failed: %v", err)
|
|
}
|
|
if !bytes.Equal(dec.Bytes(), plain) {
|
|
t.Fatalf("sm4 ccm stream mismatch")
|
|
}
|
|
}
|
|
|
|
func TestAesCCMChunkRoundTrip(t *testing.T) {
|
|
key := []byte("0123456789abcdef")
|
|
nonce := []byte("123456789012")
|
|
aad := []byte("aad")
|
|
plain := []byte("aes-ccm-chunk")
|
|
chunkIndex := uint64(5)
|
|
|
|
enc, err := EncryptAesCCMChunk(plain, key, nonce, aad, chunkIndex)
|
|
if err != nil {
|
|
t.Fatalf("EncryptAesCCMChunk failed: %v", err)
|
|
}
|
|
dec, err := DecryptAesCCMChunk(enc, key, nonce, aad, chunkIndex)
|
|
if err != nil {
|
|
t.Fatalf("DecryptAesCCMChunk failed: %v", err)
|
|
}
|
|
if !bytes.Equal(dec, plain) {
|
|
t.Fatalf("aes ccm chunk decrypt mismatch")
|
|
}
|
|
if _, err := DecryptAesCCMChunk(enc, key, nonce, aad, chunkIndex+1); err == nil {
|
|
t.Fatalf("expected decrypt error for wrong chunk index")
|
|
}
|
|
}
|
|
|
|
func TestSM4CCMChunkRoundTrip(t *testing.T) {
|
|
key := []byte("0123456789abcdef")
|
|
nonce := []byte("123456789012")
|
|
aad := []byte("aad")
|
|
plain := []byte("sm4-ccm-chunk")
|
|
chunkIndex := uint64(9)
|
|
|
|
enc, err := EncryptSM4CCMChunk(plain, key, nonce, aad, chunkIndex)
|
|
if err != nil {
|
|
t.Fatalf("EncryptSM4CCMChunk failed: %v", err)
|
|
}
|
|
dec, err := DecryptSM4CCMChunk(enc, key, nonce, aad, chunkIndex)
|
|
if err != nil {
|
|
t.Fatalf("DecryptSM4CCMChunk failed: %v", err)
|
|
}
|
|
if !bytes.Equal(dec, plain) {
|
|
t.Fatalf("sm4 ccm chunk decrypt mismatch")
|
|
}
|
|
if _, err := DecryptSM4CCMChunk(enc, key, nonce, aad, chunkIndex+1); err == nil {
|
|
t.Fatalf("expected decrypt error for wrong chunk index")
|
|
}
|
|
}
|
|
|
|
func TestAesOptionsModeCCM(t *testing.T) {
|
|
key := []byte("0123456789abcdef")
|
|
nonce := []byte("123456789012")
|
|
aad := []byte("aad")
|
|
plain := []byte("aes-options-ccm")
|
|
|
|
opts := &CipherOptions{Mode: MODECCM, Nonce: nonce, AAD: aad}
|
|
enc, err := EncryptAesWithOptions(plain, key, opts)
|
|
if err != nil {
|
|
t.Fatalf("EncryptAesWithOptions CCM failed: %v", err)
|
|
}
|
|
dec, err := DecryptAesWithOptions(enc, key, opts)
|
|
if err != nil {
|
|
t.Fatalf("DecryptAesWithOptions CCM failed: %v", err)
|
|
}
|
|
if !bytes.Equal(dec, plain) {
|
|
t.Fatalf("aes options ccm mismatch")
|
|
}
|
|
}
|
|
|
|
func TestSM4OptionsModeCCM(t *testing.T) {
|
|
key := []byte("0123456789abcdef")
|
|
nonce := []byte("123456789012")
|
|
aad := []byte("aad")
|
|
plain := []byte("sm4-options-ccm")
|
|
|
|
opts := &CipherOptions{Mode: MODECCM, Nonce: nonce, AAD: aad}
|
|
enc, err := EncryptSM4WithOptions(plain, key, opts)
|
|
if err != nil {
|
|
t.Fatalf("EncryptSM4WithOptions CCM failed: %v", err)
|
|
}
|
|
dec, err := DecryptSM4WithOptions(enc, key, opts)
|
|
if err != nil {
|
|
t.Fatalf("DecryptSM4WithOptions CCM failed: %v", err)
|
|
}
|
|
if !bytes.Equal(dec, plain) {
|
|
t.Fatalf("sm4 options ccm mismatch")
|
|
}
|
|
}
|
|
|
|
func TestCCMInvalidNonceLength(t *testing.T) {
|
|
key := []byte("0123456789abcdef")
|
|
shortNonce := []byte("short")
|
|
if _, err := EncryptAesCCM([]byte("x"), key, shortNonce, nil); err == nil {
|
|
t.Fatalf("expected aes ccm nonce length error")
|
|
}
|
|
if _, err := EncryptSM4CCM([]byte("x"), key, shortNonce, nil); err == nil {
|
|
t.Fatalf("expected sm4 ccm nonce length error")
|
|
}
|
|
}
|
|
func TestAesXTSRoundTrip(t *testing.T) {
|
|
k1 := []byte("0123456789abcdef")
|
|
k2 := []byte("fedcba9876543210")
|
|
plain := bytes.Repeat([]byte("0123456789abcdef"), 8)
|
|
|
|
enc, err := EncryptAesXTS(plain, k1, k2, 32)
|
|
if err != nil {
|
|
t.Fatalf("EncryptAesXTS failed: %v", err)
|
|
}
|
|
dec, err := DecryptAesXTS(enc, k1, k2, 32)
|
|
if err != nil {
|
|
t.Fatalf("DecryptAesXTS failed: %v", err)
|
|
}
|
|
if !bytes.Equal(dec, plain) {
|
|
t.Fatalf("aes xts mismatch")
|
|
}
|
|
}
|
|
|
|
func TestSM4XTSRoundTrip(t *testing.T) {
|
|
k1 := []byte("0123456789abcdef")
|
|
k2 := []byte("fedcba9876543210")
|
|
plain := bytes.Repeat([]byte("0123456789abcdef"), 8)
|
|
|
|
enc, err := EncryptSM4XTS(plain, k1, k2, 32)
|
|
if err != nil {
|
|
t.Fatalf("EncryptSM4XTS failed: %v", err)
|
|
}
|
|
dec, err := DecryptSM4XTS(enc, k1, k2, 32)
|
|
if err != nil {
|
|
t.Fatalf("DecryptSM4XTS failed: %v", err)
|
|
}
|
|
if !bytes.Equal(dec, plain) {
|
|
t.Fatalf("sm4 xts mismatch")
|
|
}
|
|
}
|
|
|
|
func TestAesXTSAtDataUnit(t *testing.T) {
|
|
k1 := []byte("0123456789abcdef")
|
|
k2 := []byte("fedcba9876543210")
|
|
plain := bytes.Repeat([]byte("0123456789abcdef"), 8)
|
|
dataUnitSize := 32
|
|
|
|
full, err := EncryptAesXTS(plain, k1, k2, dataUnitSize)
|
|
if err != nil {
|
|
t.Fatalf("EncryptAesXTS failed: %v", err)
|
|
}
|
|
segPlain := plain[64:96]
|
|
segEnc, err := EncryptAesXTSAt(segPlain, k1, k2, dataUnitSize, 2)
|
|
if err != nil {
|
|
t.Fatalf("EncryptAesXTSAt failed: %v", err)
|
|
}
|
|
if !bytes.Equal(segEnc, full[64:96]) {
|
|
t.Fatalf("aes xts at encrypt mismatch")
|
|
}
|
|
|
|
segDec, err := DecryptAesXTSAt(full[64:96], k1, k2, dataUnitSize, 2)
|
|
if err != nil {
|
|
t.Fatalf("DecryptAesXTSAt failed: %v", err)
|
|
}
|
|
if !bytes.Equal(segDec, segPlain) {
|
|
t.Fatalf("aes xts at decrypt mismatch")
|
|
}
|
|
}
|
|
|
|
func TestSM4XTSAtDataUnit(t *testing.T) {
|
|
k1 := []byte("0123456789abcdef")
|
|
k2 := []byte("fedcba9876543210")
|
|
plain := bytes.Repeat([]byte("0123456789abcdef"), 8)
|
|
dataUnitSize := 32
|
|
|
|
full, err := EncryptSM4XTS(plain, k1, k2, dataUnitSize)
|
|
if err != nil {
|
|
t.Fatalf("EncryptSM4XTS failed: %v", err)
|
|
}
|
|
segPlain := plain[32:64]
|
|
segEnc, err := EncryptSM4XTSAt(segPlain, k1, k2, dataUnitSize, 1)
|
|
if err != nil {
|
|
t.Fatalf("EncryptSM4XTSAt failed: %v", err)
|
|
}
|
|
if !bytes.Equal(segEnc, full[32:64]) {
|
|
t.Fatalf("sm4 xts at encrypt mismatch")
|
|
}
|
|
|
|
segDec, err := DecryptSM4XTSAt(full[32:64], k1, k2, dataUnitSize, 1)
|
|
if err != nil {
|
|
t.Fatalf("DecryptSM4XTSAt failed: %v", err)
|
|
}
|
|
if !bytes.Equal(segDec, segPlain) {
|
|
t.Fatalf("sm4 xts at decrypt mismatch")
|
|
}
|
|
}
|
|
|
|
func TestAesXTSStreamRoundTrip(t *testing.T) {
|
|
k1 := []byte("0123456789abcdef")
|
|
k2 := []byte("fedcba9876543210")
|
|
plain := bytes.Repeat([]byte("0123456789abcdef"), 2048)
|
|
|
|
enc := &bytes.Buffer{}
|
|
if err := EncryptAesXTSStream(enc, bytes.NewReader(plain), k1, k2, 512); err != nil {
|
|
t.Fatalf("EncryptAesXTSStream failed: %v", err)
|
|
}
|
|
dec := &bytes.Buffer{}
|
|
if err := DecryptAesXTSStream(dec, bytes.NewReader(enc.Bytes()), k1, k2, 512); err != nil {
|
|
t.Fatalf("DecryptAesXTSStream failed: %v", err)
|
|
}
|
|
if !bytes.Equal(dec.Bytes(), plain) {
|
|
t.Fatalf("aes xts stream mismatch")
|
|
}
|
|
}
|
|
|
|
func TestSM4XTSStreamRoundTrip(t *testing.T) {
|
|
k1 := []byte("0123456789abcdef")
|
|
k2 := []byte("fedcba9876543210")
|
|
plain := bytes.Repeat([]byte("0123456789abcdef"), 2048)
|
|
|
|
enc := &bytes.Buffer{}
|
|
if err := EncryptSM4XTSStream(enc, bytes.NewReader(plain), k1, k2, 512); err != nil {
|
|
t.Fatalf("EncryptSM4XTSStream failed: %v", err)
|
|
}
|
|
dec := &bytes.Buffer{}
|
|
if err := DecryptSM4XTSStream(dec, bytes.NewReader(enc.Bytes()), k1, k2, 512); err != nil {
|
|
t.Fatalf("DecryptSM4XTSStream failed: %v", err)
|
|
}
|
|
if !bytes.Equal(dec.Bytes(), plain) {
|
|
t.Fatalf("sm4 xts stream mismatch")
|
|
}
|
|
}
|
|
|
|
func TestXTSRejectsNonBlockMultiple(t *testing.T) {
|
|
k1 := []byte("0123456789abcdef")
|
|
k2 := []byte("fedcba9876543210")
|
|
if _, err := EncryptAesXTS([]byte("short"), k1, k2, 32); err == nil {
|
|
t.Fatalf("expected aes xts non-block error")
|
|
}
|
|
if _, err := EncryptSM4XTS([]byte("short"), k1, k2, 32); err == nil {
|
|
t.Fatalf("expected sm4 xts non-block error")
|
|
}
|
|
}
|
|
|
|
func TestXTSStreamRejectsTailNotFullBlock(t *testing.T) {
|
|
k1 := []byte("0123456789abcdef")
|
|
k2 := []byte("fedcba9876543210")
|
|
err := EncryptAesXTSStream(&bytes.Buffer{}, bytes.NewReader([]byte("tail-not-16")), k1, k2, 32)
|
|
if err == nil {
|
|
t.Fatalf("expected aes xts stream tail error")
|
|
}
|
|
err = EncryptSM4XTSStream(&bytes.Buffer{}, bytes.NewReader([]byte("tail-not-16")), k1, k2, 32)
|
|
if err == nil {
|
|
t.Fatalf("expected sm4 xts stream tail error")
|
|
}
|
|
}
|
|
|
|
func TestXTSInvalidDataUnitSize(t *testing.T) {
|
|
k1 := []byte("0123456789abcdef")
|
|
k2 := []byte("fedcba9876543210")
|
|
plain := bytes.Repeat([]byte("0123456789abcdef"), 2)
|
|
if _, err := EncryptAesXTS(plain, k1, k2, 30); err == nil {
|
|
t.Fatalf("expected aes xts invalid data unit size error")
|
|
}
|
|
if _, err := EncryptSM4XTS(plain, k1, k2, 30); err == nil {
|
|
t.Fatalf("expected sm4 xts invalid data unit size error")
|
|
}
|
|
}
|
|
func TestSplitXTSMasterKeyHelpers(t *testing.T) {
|
|
master := []byte("0123456789abcdef0123456789abcdef")
|
|
|
|
k1, k2, err := SplitXTSMasterKey(master)
|
|
if err != nil {
|
|
t.Fatalf("SplitXTSMasterKey failed: %v", err)
|
|
}
|
|
if len(k1) != 16 || len(k2) != 16 {
|
|
t.Fatalf("split key lengths mismatch")
|
|
}
|
|
if !bytes.Equal(append(k1, k2...), master) {
|
|
t.Fatalf("split key content mismatch")
|
|
}
|
|
|
|
aesK1, aesK2, err := SplitAesXTSMasterKey(master)
|
|
if err != nil {
|
|
t.Fatalf("SplitAesXTSMasterKey failed: %v", err)
|
|
}
|
|
if !bytes.Equal(aesK1, k1) || !bytes.Equal(aesK2, k2) {
|
|
t.Fatalf("aes split mismatch")
|
|
}
|
|
|
|
sm4K1, sm4K2, err := SplitSM4XTSMasterKey(master)
|
|
if err != nil {
|
|
t.Fatalf("SplitSM4XTSMasterKey failed: %v", err)
|
|
}
|
|
if !bytes.Equal(sm4K1, k1) || !bytes.Equal(sm4K2, k2) {
|
|
t.Fatalf("sm4 split mismatch")
|
|
}
|
|
|
|
if _, _, err := SplitXTSMasterKey([]byte("abc")); err == nil {
|
|
t.Fatalf("expected odd-length split error")
|
|
}
|
|
if _, _, err := SplitAesXTSMasterKey([]byte("0123456789abcdef0123456789abcdef01")); err == nil {
|
|
t.Fatalf("expected aes master length error")
|
|
}
|
|
if _, _, err := SplitSM4XTSMasterKey([]byte("0123456789abcdef")); err == nil {
|
|
t.Fatalf("expected sm4 master length error")
|
|
}
|
|
}
|