github.com/bigzoro/my_simplechain@v0.0.0-20240315012955-8ad0a2a29bb9/core/access_contoller/crypto/sdf/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 sdf
     9  
    10  import (
    11  	"encoding/asn1"
    12  	"fmt"
    13  	"math/big"
    14  
    15  	"github.com/pkg/errors"
    16  
    17  	"chainmaker.org/chainmaker/common/v2/crypto/hsm"
    18  
    19  	"chainmaker.org/chainmaker/common/v2/crypto/sdf/base"
    20  	"github.com/tjfoc/gmsm/sm2"
    21  )
    22  
    23  type SDFKey struct {
    24  	KeyId   uint
    25  	KeyPwd  []byte
    26  	KeyType SDFKeyType
    27  }
    28  
    29  func (h *SDFHandle) GenerateRandom(length int) ([]byte, error) {
    30  	session, err := h.getSession()
    31  	if err != nil {
    32  		return nil, fmt.Errorf("[SDF] error: fail to get session [%s]", err)
    33  	}
    34  	defer h.returnSession(err, session)
    35  
    36  	return h.ctx.SDFGenerateRandom(session, uint(length))
    37  }
    38  
    39  // Sign signs the input with a given mechanism.
    40  func (h *SDFHandle) ECCInternalSign(key SDFKey, msg []byte) ([]byte, error) {
    41  	session, err := h.getSession()
    42  	if err != nil {
    43  		return nil, fmt.Errorf("[SDF] error: fail to get session [%s]", err)
    44  	}
    45  	defer h.returnSession(err, session)
    46  
    47  	{
    48  		/*
    49  			check pwd
    50  			this depends on HSM vendors :-(
    51  		*/
    52  		accessKeyId, need := hsm.GetHSMAdapter("").SDF_GetSM2KeyAccessRight(int(key.KeyId))
    53  		if need {
    54  			err = h.ctx.SDFGetPrivateKeyAccessRight(session, uint(accessKeyId), key.KeyPwd, uint(len(key.KeyPwd)))
    55  			if err != nil {
    56  				return nil, errors.WithMessage(err, "failed to SDFGetPrivateKeyAccessRight before sign")
    57  			}
    58  		}
    59  	}
    60  
    61  	sign, err := h.ctx.SDFInternalSign_ECC(session, key.KeyId, msg, uint(len(msg)))
    62  	if err != nil {
    63  		return nil, errors.WithMessage(err, "failed to SDFInternalSign_ECC")
    64  	}
    65  	r := big.NewInt(0).SetBytes([]byte(sign.R))
    66  	s := big.NewInt(0).SetBytes([]byte(sign.S))
    67  
    68  	return asn1.Marshal(ECCSignature{r, s})
    69  }
    70  
    71  // Verify verifies a signature over a message with a given mechanism.
    72  func (h *SDFHandle) Verify(key SDFKey, msg []byte, sig base.ECCSignature) error {
    73  	session, err := h.getSession()
    74  	if err != nil {
    75  		return fmt.Errorf("[SDF] error: fail to get session [%s]", err)
    76  	}
    77  	defer h.returnSession(err, session)
    78  
    79  	//err = h.ctx.SDFGetPrivateKeyAccessRight(session, key.KeyId, key.KeyPwd, uint(len(key.KeyPwd)))
    80  	//if err != nil {
    81  	//	return err
    82  	//}
    83  
    84  	err = h.ctx.SDFInternalVerify_ECC(session, key.KeyId, msg, uint(len(msg)), sig)
    85  	if err != nil {
    86  		return err
    87  	}
    88  	return nil
    89  }
    90  
    91  // Encrypt encrypts a plaintext with a given mechanism.
    92  func (h *SDFHandle) Encrypt(key SDFKey, plain []byte) ([]byte, error) {
    93  	session, err := h.getSession()
    94  	if err != nil {
    95  		return nil, fmt.Errorf("[SDF] error: fail to get session [%s]", err)
    96  	}
    97  	defer h.returnSession(err, session)
    98  
    99  	{
   100  		/*
   101  			check pwd
   102  			this depends on HSM vendors :-(
   103  		*/
   104  		accessKeyId, need := hsm.GetHSMAdapter("").SDF_GetSM2KeyAccessRight(int(key.KeyId))
   105  		if need {
   106  			err = h.ctx.SDFGetPrivateKeyAccessRight(session, uint(accessKeyId), key.KeyPwd, uint(len(key.KeyPwd)))
   107  			if err != nil {
   108  				return nil, err
   109  			}
   110  		}
   111  	}
   112  
   113  	out, err := h.ctx.SDFInternalEncrypt_ECC(session, key.KeyId, base.SGD_SM2_3, plain, uint(len(plain)))
   114  	if err != nil {
   115  		return nil, errors.WithMessagef(err, "failed to execute sm2 encrypt")
   116  	}
   117  	return asn1.Marshal(out)
   118  }
   119  
   120  // Encrypt encrypts a plaintext with a given mechanism.
   121  func (h *SDFHandle) Decrypt(key SDFKey, cipher []byte) ([]byte, error) {
   122  	session, err := h.getSession()
   123  	if err != nil {
   124  		return nil, fmt.Errorf("[SDF] error: fail to get session [%s]", err)
   125  	}
   126  	defer h.returnSession(err, session)
   127  
   128  	{
   129  		/*
   130  			check pwd
   131  			this depends on HSM vendors :-(
   132  		*/
   133  		accessKeyId, need := hsm.GetHSMAdapter("").SDF_GetSM2KeyAccessRight(int(key.KeyId))
   134  		if need {
   135  			err = h.ctx.SDFGetPrivateKeyAccessRight(session, uint(accessKeyId), key.KeyPwd, uint(len(key.KeyPwd)))
   136  			if err != nil {
   137  				return nil, err
   138  			}
   139  		}
   140  	}
   141  
   142  	//out, _, err := h.ctx.SDFInternalDecrypt_ECC(session, key.KeyId, sdf.SGD_SM2_3, cipher)
   143  	//if err != nil {
   144  	//	return nil, err
   145  	//}
   146  	//_ = out
   147  	return nil, nil
   148  }
   149  
   150  // GenKeyPair returns asym keypair
   151  func (h *SDFHandle) GenKeyPair() (pri *base.ECCrefPrivateKey, pub *base.ECCrefPublicKey, err error) {
   152  	session, err := h.getSession()
   153  	if err != nil {
   154  		return nil, nil, fmt.Errorf("[SDF] error: fail to get session [%s]", err)
   155  	}
   156  	defer h.returnSession(err, session)
   157  
   158  	pubHandle, privHandle, err := h.ctx.SDFGenerateKeyPair_ECC(session, base.SGD_SM2, 256)
   159  	if err != nil {
   160  		return nil, nil, err
   161  	}
   162  	return &privHandle, &pubHandle, nil
   163  }
   164  
   165  // GenerateKey returns sym key
   166  func (h *SDFHandle) GenerateKey(length int) ([]byte, error) {
   167  	session, err := h.getSession()
   168  	if err != nil {
   169  		return nil, fmt.Errorf("[SDF] error: fail to get session [%s]", err)
   170  	}
   171  	defer h.returnSession(err, session)
   172  
   173  	randomBytes, err := h.ctx.SDFGenerateRandom(session, uint(length))
   174  	if err != nil {
   175  		return nil, err
   176  	}
   177  	return randomBytes, nil
   178  }
   179  
   180  // ExportECDSAPublicKey export a ecdsa/sm2 public key of pkcs11 ecdsa/sm2 private key
   181  func (h *SDFHandle) ExportECDSAPublicKey(key SDFKey) (interface{}, error) {
   182  	session, err := h.getSession()
   183  	if err != nil {
   184  		return nil, fmt.Errorf("[SDF] error: fail to get session [%s]", err)
   185  	}
   186  	defer h.returnSession(err, session)
   187  
   188  	pub, err := h.ctx.SDFExportSignPublicKey_ECC(session, key.KeyId)
   189  	if err != nil {
   190  		return nil, err
   191  	}
   192  
   193  	x, y := big.NewInt(0), big.NewInt(0)
   194  	x.SetBytes([]byte(pub.X))
   195  	y.SetBytes([]byte(pub.Y))
   196  
   197  	sm2PubKey := &sm2.PublicKey{
   198  		Curve: sm2.P256Sm2(),
   199  		X:     x,
   200  		Y:     y,
   201  	}
   202  
   203  	return sm2PubKey, err
   204  }
   205  
   206  // Encrypt encrypts a plaintext with a given mechanism.
   207  func (h *SDFHandle) SymEncrypt(keyHandle base.SessionHandle, mode uint, iv []byte, plain []byte) ([]byte, error) {
   208  	session, err := h.getSession()
   209  	if err != nil {
   210  		return nil, fmt.Errorf("[SDF] error: fail to get session [%s]", err)
   211  	}
   212  	defer h.returnSession(err, session)
   213  
   214  	iv2 := make([]byte, len(iv))
   215  	copy(iv2, iv)
   216  	encData, encDataLength, err := h.ctx.SDFEncrypt(session, keyHandle, mode, iv2, plain, uint(len(plain)))
   217  	if err != nil {
   218  		return nil, errors.WithMessage(err, "failed to encrypt")
   219  	}
   220  	return encData[:encDataLength], nil
   221  }
   222  
   223  // Encrypt encrypts a plaintext with a given mechanism.
   224  func (h *SDFHandle) SymDecrypt(keyHandle base.SessionHandle, mode uint, iv []byte, cipher []byte) ([]byte, error) {
   225  	session, err := h.getSession()
   226  	if err != nil {
   227  		return nil, fmt.Errorf("[SDF] error: fail to get session [%s]", err)
   228  	}
   229  	defer h.returnSession(err, session)
   230  
   231  	iv2 := make([]byte, len(iv))
   232  	copy(iv2, iv)
   233  	decdata, decdataLength, err := h.ctx.SDFDecrypt(session, keyHandle, mode, iv2, cipher, uint(len(cipher)))
   234  	if err != nil {
   235  		return nil, errors.WithMessage(err, "failed to decrypt")
   236  	}
   237  	return decdata[:decdataLength], nil
   238  }