github.com/bigzoro/my_simplechain@v0.0.0-20240315012955-8ad0a2a29bb9/core/access_contoller/crypto/pkcs11/aeskey.go (about)

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