gitee.com/lh-her-team/common@v1.5.1/crypto/pkcs11/sm4key.go (about) 1 package pkcs11 2 3 import ( 4 "crypto/rand" 5 "fmt" 6 "strconv" 7 8 "gitee.com/lh-her-team/common/crypto/hsm" 9 10 "gitee.com/lh-her-team/common/crypto/sym/util" 11 12 bccrypto "gitee.com/lh-her-team/common/crypto" 13 "gitee.com/lh-her-team/common/crypto/sym/modes" 14 "github.com/miekg/pkcs11" 15 "github.com/pkg/errors" 16 ) 17 18 var defaultSM4Opts = &bccrypto.EncOpts{ 19 EncodingType: modes.PADDING_PKCS5, 20 BlockMode: modes.BLOCK_MODE_CBC, 21 EnableMAC: true, 22 Hash: 0, 23 Label: nil, 24 EnableASN1: false, 25 } 26 27 var _ bccrypto.SymmetricKey = (*sm4Key)(nil) 28 29 type sm4Key struct { 30 p11Ctx *P11Handle 31 keyId []byte 32 keyType P11KeyType 33 keyObject pkcs11.ObjectHandle 34 blockSize int 35 } 36 37 func NewSM4Key(ctx *P11Handle, keyId []byte) (bccrypto.SymmetricKey, error) { 38 //find private key 39 id, err := strconv.Atoi(string(keyId)) 40 if err != nil { 41 return nil, err 42 } 43 keyIdStr, err := hsm.GetHSMAdapter("").PKCS11_GetSM4KeyId(id) 44 if err != nil { 45 return nil, err 46 } 47 obj, err := ctx.findSecretKey([]byte(keyIdStr)) 48 if err != nil { 49 return nil, fmt.Errorf("PKCS11 error: fail to find sm4 key [%s]", err) 50 } 51 return &sm4Key{ 52 p11Ctx: ctx, 53 keyId: keyId, 54 keyObject: *obj, 55 keyType: SM4, 56 blockSize: 16, 57 }, nil 58 } 59 60 func (s *sm4Key) Bytes() ([]byte, error) { 61 return s.keyId, nil 62 } 63 64 func (s *sm4Key) Type() bccrypto.KeyType { 65 return bccrypto.SM4 66 } 67 68 func (s *sm4Key) String() (string, error) { 69 return string(s.keyId), nil 70 } 71 72 func (s *sm4Key) Encrypt(plain []byte) ([]byte, error) { 73 return s.EncryptWithOpts(plain, defaultSM4Opts) 74 } 75 76 func (s *sm4Key) EncryptWithOpts(plain []byte, opts *bccrypto.EncOpts) ([]byte, error) { 77 iv := make([]byte, s.blockSize) 78 if _, err := rand.Read(iv); err != nil { 79 return nil, err 80 } 81 var cipherWithPad []byte 82 switch opts.BlockMode { 83 case modes.BLOCK_MODE_CBC: 84 switch opts.EncodingType { 85 case modes.PADDING_PKCS5: 86 plainWithPad := util.PKCS5Padding(plain, s.blockSize) 87 ciphertex, err := s.p11Ctx.Encrypt(s.keyObject, pkcs11.NewMechanism(CKM_SM4_CBC, iv), plainWithPad) 88 if err != nil { 89 return nil, err 90 } 91 cipherWithPad = append(iv, ciphertex...) 92 default: 93 return nil, fmt.Errorf("sm4 CBC encryption fails: invalid padding scheme [%s]", opts.EncodingType) 94 } 95 default: 96 return nil, fmt.Errorf("sm4 encryption fails: unknown cipher block mode [%s]", opts.BlockMode) 97 } 98 return cipherWithPad, nil 99 } 100 101 func (s *sm4Key) Decrypt(ciphertext []byte) ([]byte, error) { 102 return s.DecryptWithOpts(ciphertext, defaultSM4Opts) 103 } 104 105 func (s *sm4Key) DecryptWithOpts(ciphertext []byte, opts *bccrypto.EncOpts) ([]byte, error) { 106 if len(ciphertext) < s.blockSize { 107 return nil, errors.New("invalid ciphertext length") 108 } 109 var plain []byte 110 switch opts.BlockMode { 111 case modes.BLOCK_MODE_CBC: 112 switch opts.EncodingType { 113 case modes.PADDING_PKCS5: 114 iv := ciphertext[:s.blockSize] 115 out, err := s.p11Ctx.Decrypt(s.keyObject, pkcs11.NewMechanism(CKM_SM4_CBC, iv), ciphertext[s.blockSize:]) 116 if err != nil { 117 return nil, fmt.Errorf("PKCS11 error: fail to encrypt [%s]", err) 118 } 119 plain, err = util.PKCS5UnPadding(out) 120 if err != nil { 121 return nil, err 122 } 123 default: 124 return nil, fmt.Errorf("sm4 CBC encryption fails: invalid padding scheme [%s]", opts.EncodingType) 125 } 126 default: 127 return nil, fmt.Errorf("sm4 encryption fails: unknown cipher block mode [%s]", opts.BlockMode) 128 } 129 return plain, nil 130 }