From af50b136e93290da7fcd5dc9d0cd8b9a9caf8f71 Mon Sep 17 00:00:00 2001 From: Sun Yimin Date: Tue, 19 Jul 2022 13:29:21 +0800 Subject: [PATCH] sm4: separate cipher_ni from cipher_asm --- .github/codecov.yaml | 1 + pkcs8/pkcs8_test.go | 41 ++++++++++++++++++++++++++++++++++++ sm4/cipher_asm.go | 39 ----------------------------------- sm4/cipher_ni.go | 49 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 91 insertions(+), 39 deletions(-) create mode 100644 sm4/cipher_ni.go diff --git a/.github/codecov.yaml b/.github/codecov.yaml index a71a9e8..3ba7cf3 100644 --- a/.github/codecov.yaml +++ b/.github/codecov.yaml @@ -4,3 +4,4 @@ codecov: ignore: - "sm2/gen_p256_table.go" - "sm4/sm4ni_gcm_asm.go" + - "sm4/cipher_ni.go" diff --git a/pkcs8/pkcs8_test.go b/pkcs8/pkcs8_test.go index e35dd1c..f256edf 100644 --- a/pkcs8/pkcs8_test.go +++ b/pkcs8/pkcs8_test.go @@ -5,6 +5,8 @@ import ( "crypto/elliptic" "crypto/rand" "crypto/rsa" + "crypto/x509/pkix" + "encoding/asn1" "encoding/pem" "testing" @@ -598,3 +600,42 @@ func TestUnknownTypeFailure(t *testing.T) { t.Fatal("expected error") } } + +// for encrypted private-key information +type encryptedPrivateKeyInfo struct { + EncryptionAlgorithm pkix.AlgorithmIdentifier + EncryptedData []byte +} + +func TestParseInvalidPrivateKey(t *testing.T) { + // test parse pem directly + _, err := pkcs8.ParsePKCS8PrivateKeyECDSA([]byte(encryptedEC256aes), []byte("password")) + if err == nil || err.Error() != "pkcs8: this method just supports DER-encoded key" { + t.Errorf("should be error: pkcs8: this method just supports DER-encoded key") + } + _, err = pkcs8.ParsePKCS8PrivateKeyECDSA(nil, []byte("password")) + if err == nil || err.Error() != "pkcs8: only PKCS #5 v2.0 supported" { + t.Errorf("should be error: pkcs8: only PKCS #5 v2.0 supported") + } + + var privKey encryptedPrivateKeyInfo + privKey.EncryptionAlgorithm.Algorithm = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 5, 1} + data, err := asn1.Marshal(privKey) + if err != nil { + t.Fatal(err) + } + _, err = pkcs8.ParsePKCS8PrivateKeyECDSA(data, []byte("password")) + if err == nil || err.Error() != "pkcs8: only PBES2 supported" { + t.Errorf("should be error: pkcs8: only PBES2 supported") + } + + privKey.EncryptionAlgorithm.Algorithm = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 5, 13} + data, err = asn1.Marshal(privKey) + if err != nil { + t.Fatal(err) + } + _, err = pkcs8.ParsePKCS8PrivateKeyECDSA(data, []byte("password")) + if err == nil || err.Error() != "pkcs8: invalid PBES2 parameters" { + t.Errorf("should be error: pkcs8: invalid PBES2 parameters") + } +} diff --git a/sm4/cipher_asm.go b/sm4/cipher_asm.go index 1eadf21..0a0b6a9 100644 --- a/sm4/cipher_asm.go +++ b/sm4/cipher_asm.go @@ -35,45 +35,6 @@ type sm4CipherAsm struct { blocksSize int } -type sm4CipherNI struct { - sm4Cipher -} - -func newCipherNI(key []byte) (cipher.Block, error) { - c := &sm4CipherNI{sm4Cipher{make([]uint32, rounds), make([]uint32, rounds)}} - expandKeyAsm(&key[0], &ck[0], &c.enc[0], &c.dec[0], INST_SM4) - if supportsGFMUL { - return &sm4CipherNIGCM{c}, nil - } - return c, nil -} - -func (c *sm4CipherNI) Encrypt(dst, src []byte) { - if len(src) < BlockSize { - panic("sm4: input not full block") - } - if len(dst) < BlockSize { - panic("sm4: output not full block") - } - if subtle.InexactOverlap(dst[:BlockSize], src[:BlockSize]) { - panic("sm4: invalid buffer overlap") - } - encryptBlockAsm(&c.enc[0], &dst[0], &src[0], INST_SM4) -} - -func (c *sm4CipherNI) Decrypt(dst, src []byte) { - if len(src) < BlockSize { - panic("sm4: input not full block") - } - if len(dst) < BlockSize { - panic("sm4: output not full block") - } - if subtle.InexactOverlap(dst[:BlockSize], src[:BlockSize]) { - panic("sm4: invalid buffer overlap") - } - encryptBlockAsm(&c.dec[0], &dst[0], &src[0], INST_SM4) -} - func newCipher(key []byte) (cipher.Block, error) { if supportSM4 { return newCipherNI(key) diff --git a/sm4/cipher_ni.go b/sm4/cipher_ni.go new file mode 100644 index 0000000..541af67 --- /dev/null +++ b/sm4/cipher_ni.go @@ -0,0 +1,49 @@ +//go:build (amd64 && !generic) || (arm64 && !generic) +// +build amd64,!generic arm64,!generic + +package sm4 + +import ( + "crypto/cipher" + + "github.com/emmansun/gmsm/internal/subtle" +) + +type sm4CipherNI struct { + sm4Cipher +} + +func newCipherNI(key []byte) (cipher.Block, error) { + c := &sm4CipherNI{sm4Cipher{make([]uint32, rounds), make([]uint32, rounds)}} + expandKeyAsm(&key[0], &ck[0], &c.enc[0], &c.dec[0], INST_SM4) + if supportsGFMUL { + return &sm4CipherNIGCM{c}, nil + } + return c, nil +} + +func (c *sm4CipherNI) Encrypt(dst, src []byte) { + if len(src) < BlockSize { + panic("sm4: input not full block") + } + if len(dst) < BlockSize { + panic("sm4: output not full block") + } + if subtle.InexactOverlap(dst[:BlockSize], src[:BlockSize]) { + panic("sm4: invalid buffer overlap") + } + encryptBlockAsm(&c.enc[0], &dst[0], &src[0], INST_SM4) +} + +func (c *sm4CipherNI) Decrypt(dst, src []byte) { + if len(src) < BlockSize { + panic("sm4: input not full block") + } + if len(dst) < BlockSize { + panic("sm4: output not full block") + } + if subtle.InexactOverlap(dst[:BlockSize], src[:BlockSize]) { + panic("sm4: invalid buffer overlap") + } + encryptBlockAsm(&c.dec[0], &dst[0], &src[0], INST_SM4) +}