github.com/bigzoro/my_simplechain@v0.0.0-20240315012955-8ad0a2a29bb9/core/access_contoller/crypto/pkcs11/crypto.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  	"bytes"
    12  	"crypto/ecdsa"
    13  	"crypto/elliptic"
    14  	"crypto/rsa"
    15  	"encoding/binary"
    16  	"fmt"
    17  	"math/big"
    18  
    19  	"github.com/pkg/errors"
    20  	"github.com/tjfoc/gmsm/sm2"
    21  
    22  	"github.com/miekg/pkcs11"
    23  )
    24  
    25  func (p11 *P11Handle) GenerateRandom(length int) ([]byte, error) {
    26  	session, err := p11.getSession()
    27  	if err != nil {
    28  		return nil, fmt.Errorf("PKCS11 error: fail to get session [%s]", err)
    29  	}
    30  	defer p11.returnSession(err, session)
    31  
    32  	return p11.ctx.GenerateRandom(session, length)
    33  }
    34  
    35  // Decrypt decrypts the input with a given mechanism.
    36  func (p11 *P11Handle) Decrypt(obj pkcs11.ObjectHandle, mech *pkcs11.Mechanism, cipher []byte) ([]byte, error) {
    37  	session, err := p11.getSession()
    38  	if err != nil {
    39  		return nil, fmt.Errorf("PKCS11 error: fail to get session [%s]", err)
    40  	}
    41  	defer p11.returnSession(err, session)
    42  
    43  	err = p11.ctx.DecryptInit(session, []*pkcs11.Mechanism{mech}, obj)
    44  	if err != nil {
    45  		return nil, err
    46  	}
    47  	out, err := p11.ctx.Decrypt(session, cipher)
    48  	if err != nil {
    49  		return nil, err
    50  	}
    51  	return out, nil
    52  }
    53  
    54  // Sign signs the input with a given mechanism.
    55  func (p11 *P11Handle) Sign(obj pkcs11.ObjectHandle, mech *pkcs11.Mechanism, msg []byte) ([]byte, error) {
    56  	session, err := p11.getSession()
    57  	if err != nil {
    58  		return nil, fmt.Errorf("PKCS11 error: fail to get session [%s]", err)
    59  	}
    60  	defer p11.returnSession(err, session)
    61  
    62  	err = p11.ctx.SignInit(session, []*pkcs11.Mechanism{mech}, obj)
    63  	if err != nil {
    64  		return nil, err
    65  	}
    66  	out, err := p11.ctx.Sign(session, msg)
    67  	if err != nil {
    68  		return nil, err
    69  	}
    70  	return out, nil
    71  }
    72  
    73  // Verify verifies a signature over a message with a given mechanism.
    74  func (p11 *P11Handle) Verify(obj pkcs11.ObjectHandle, mech *pkcs11.Mechanism, msg, sig []byte) error {
    75  	session, err := p11.getSession()
    76  	if err != nil {
    77  		return fmt.Errorf("PKCS11 error: fail to get session [%s]", err)
    78  	}
    79  	defer p11.returnSession(err, session)
    80  
    81  	err = p11.ctx.VerifyInit(session, []*pkcs11.Mechanism{mech}, obj)
    82  	if err != nil {
    83  		return err
    84  	}
    85  	err = p11.ctx.Verify(session, msg, sig)
    86  	if err != nil {
    87  		return err
    88  	}
    89  	return nil
    90  }
    91  
    92  // Encrypt encrypts a plaintext with a given mechanism.
    93  func (p11 *P11Handle) Encrypt(obj pkcs11.ObjectHandle, mech *pkcs11.Mechanism, plain []byte) ([]byte, error) {
    94  	session, err := p11.getSession()
    95  	if err != nil {
    96  		return nil, fmt.Errorf("PKCS11 error: fail to get session [%s]", err)
    97  	}
    98  	defer p11.returnSession(err, session)
    99  
   100  	err = p11.ctx.EncryptInit(session, []*pkcs11.Mechanism{mech}, obj)
   101  	if err != nil {
   102  		return nil, err
   103  	}
   104  	out, err := p11.ctx.Encrypt(session, plain)
   105  	if err != nil {
   106  		return nil, err
   107  	}
   108  	return out, nil
   109  }
   110  
   111  // GenKeyPair returns asym keypair
   112  func (p11 *P11Handle) GenKeyPair(mech *pkcs11.Mechanism, privAttrs,
   113  	pubAttrs []*pkcs11.Attribute) (pri, pub *pkcs11.ObjectHandle, err error) {
   114  	session, err := p11.getSession()
   115  	if err != nil {
   116  		return nil, nil, fmt.Errorf("PKCS11 error: fail to get session [%s]", err)
   117  	}
   118  	defer p11.returnSession(err, session)
   119  
   120  	pubHandle, privHandle, err := p11.ctx.GenerateKeyPair(session, []*pkcs11.Mechanism{mech}, pubAttrs, privAttrs)
   121  	if err != nil {
   122  		return nil, nil, err
   123  	}
   124  	return &privHandle, &pubHandle, nil
   125  }
   126  
   127  // GenerateKey returns sym key
   128  func (p11 *P11Handle) GenerateKey(mech *pkcs11.Mechanism, attrs []*pkcs11.Attribute) (*pkcs11.ObjectHandle, error) {
   129  	session, err := p11.getSession()
   130  	if err != nil {
   131  		return nil, fmt.Errorf("PKCS11 error: fail to get session [%s]", err)
   132  	}
   133  	defer p11.returnSession(err, session)
   134  
   135  	keyHandle, err := p11.ctx.GenerateKey(session, []*pkcs11.Mechanism{mech}, attrs)
   136  	if err != nil {
   137  		return nil, err
   138  	}
   139  	return &keyHandle, nil
   140  }
   141  
   142  // ExportRSAPublicKey export a rsa public key of pkcs11 rsa private key
   143  func (p11 *P11Handle) ExportRSAPublicKey(id []byte) (*rsa.PublicKey, error) {
   144  	template := []*pkcs11.Attribute{
   145  		pkcs11.NewAttribute(pkcs11.CKA_PUBLIC_EXPONENT, nil),
   146  		pkcs11.NewAttribute(pkcs11.CKA_MODULUS, nil),
   147  	}
   148  	attrs, err := p11.getAttributes(id, template)
   149  	if err != nil {
   150  		return nil, err
   151  	}
   152  	n, e := big.NewInt(0), int(0)
   153  	for _, a := range attrs {
   154  		if a.Type == pkcs11.CKA_MODULUS {
   155  			n.SetBytes(a.Value)
   156  		} else if a.Type == pkcs11.CKA_PUBLIC_EXPONENT {
   157  			bigE := big.NewInt(0)
   158  			bigE.SetBytes(a.Value)
   159  			e = int(bigE.Int64())
   160  		}
   161  	}
   162  	if e == 0 || n.Cmp(big.NewInt(0)) == 0 {
   163  		return nil, errors.New("public key missing either modulus or exponent")
   164  	}
   165  
   166  	return &rsa.PublicKey{
   167  		N: n,
   168  		E: e,
   169  	}, nil
   170  }
   171  
   172  // ExportECDSAPublicKey export a ecdsa/sm2 public key of pkcs11 ecdsa/sm2 private key
   173  func (p11 *P11Handle) ExportECDSAPublicKey(id []byte, keyType P11KeyType) (interface{}, error) {
   174  	template := []*pkcs11.Attribute{
   175  		pkcs11.NewAttribute(pkcs11.CKA_EC_PARAMS, nil),
   176  		pkcs11.NewAttribute(pkcs11.CKA_EC_POINT, nil),
   177  		//pkcs11.NewAttribute(pkcs11.CKA_LABEL, nil),
   178  		//pkcs11.NewAttribute(pkcs11.CKA_PUBLIC_KEY_INFO, nil), //PKCS#11 specification v2.40 support!
   179  	}
   180  	attrs, err := p11.getAttributes(id, template)
   181  	if err != nil {
   182  		return nil, err
   183  	}
   184  	if len(attrs) < 2 {
   185  		return nil, errors.New("Got attribute not enough, should greater than 2")
   186  	}
   187  
   188  	var curve elliptic.Curve
   189  	if keyType == SM2 {
   190  		curve = sm2.P256Sm2()
   191  	} else {
   192  		curve, err = unmarshalEcParams(attrs[0].Value)
   193  		if err != nil {
   194  			return nil, err
   195  		}
   196  	}
   197  
   198  	x, y, err := unmarshalEcPoint(curve, attrs[1].Value)
   199  	if err != nil {
   200  		return nil, err
   201  	}
   202  
   203  	if keyType == SM2 {
   204  		return &sm2.PublicKey{Curve: curve, X: x, Y: y}, nil
   205  	}
   206  	return &ecdsa.PublicKey{Curve: curve, X: x, Y: y}, nil
   207  }
   208  
   209  // getSecretKeySize returns a pkcs11 secret key length
   210  func (p11 *P11Handle) getSecretKeySize(obj pkcs11.ObjectHandle) (int, error) {
   211  	session, err := p11.getSession()
   212  	if err != nil {
   213  		return 0, errors.WithMessage(err, "failed to get pkcs11 session")
   214  	}
   215  	defer p11.returnSession(err, session)
   216  
   217  	//CKA_VALUE_LEN
   218  	template := []*pkcs11.Attribute{
   219  		pkcs11.NewAttribute(pkcs11.CKA_VALUE_LEN, nil),
   220  	}
   221  	attrs, err := p11.ctx.GetAttributeValue(session, obj, template)
   222  	if err != nil {
   223  		return 0, errors.WithMessage(err, "failed to get aes key CKA_VALUE_LEN")
   224  	}
   225  	if len(attrs) == 1 {
   226  		return bytesToInt(attrs[0].Value)
   227  	}
   228  
   229  	//CKA_VALUE
   230  	template = []*pkcs11.Attribute{
   231  		pkcs11.NewAttribute(pkcs11.CKA_VALUE, nil),
   232  	}
   233  	attrs, err = p11.ctx.GetAttributeValue(session, obj, template)
   234  	if err != nil {
   235  		return 0, errors.WithMessage(err, "failed to get aes key attribute")
   236  	}
   237  	if attrs == nil || len(attrs) < 1 {
   238  		return 0, errors.New("attributes is empty")
   239  	}
   240  	return len(attrs[0].Value), nil
   241  }
   242  
   243  // bytesToInt le bytes to int32, little endian
   244  func bytesToInt(b []byte) (int, error) {
   245  	bytesBuffer := bytes.NewBuffer(b)
   246  
   247  	var x uint32
   248  	err := binary.Read(bytesBuffer, binary.LittleEndian, &x)
   249  	if err != nil {
   250  		return -1, err
   251  	}
   252  	return int(x), nil
   253  }