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