github.com/bigzoro/my_simplechain@v0.0.0-20240315012955-8ad0a2a29bb9/core/access_contoller/crypto/pkcs11/curve.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/elliptic"
    13  	"encoding/asn1"
    14  	"math/big"
    15  
    16  	"github.com/tjfoc/gmsm/sm2"
    17  
    18  	"github.com/pkg/errors"
    19  )
    20  
    21  var errUnsupportedEllipticCurve = errors.New("unsupported elliptic curve")
    22  
    23  // Information about an Elliptic Curve
    24  type curveInfo struct {
    25  	oid   []byte
    26  	curve elliptic.Curve
    27  }
    28  
    29  var knownCurves = map[string]curveInfo{
    30  	"P-224": {
    31  		mustMarshal(asn1.ObjectIdentifier{1, 3, 132, 0, 33}),
    32  		elliptic.P224(),
    33  	},
    34  	"P-256": {
    35  		mustMarshal(asn1.ObjectIdentifier{1, 2, 840, 10045, 3, 1, 7}),
    36  		elliptic.P256(),
    37  	},
    38  	"P-384": {
    39  		mustMarshal(asn1.ObjectIdentifier{1, 3, 132, 0, 34}),
    40  		elliptic.P384(),
    41  	},
    42  	"P-521": {
    43  		mustMarshal(asn1.ObjectIdentifier{1, 3, 132, 0, 35}),
    44  		elliptic.P521(),
    45  	},
    46  
    47  	"SM2": {
    48  		mustMarshal(asn1.ObjectIdentifier{1, 2, 156, 10197, 1, 301}),
    49  		sm2.P256Sm2(),
    50  	},
    51  }
    52  
    53  func mustMarshal(val interface{}) []byte {
    54  	b, _ := asn1.Marshal(val)
    55  	return b
    56  }
    57  
    58  func unmarshalEcParams(oid []byte) (elliptic.Curve, error) {
    59  	for _, ci := range knownCurves {
    60  		if bytes.Equal(oid, ci.oid) {
    61  			if ci.curve != nil {
    62  				return ci.curve, nil
    63  			}
    64  			return nil, errUnsupportedEllipticCurve
    65  		}
    66  	}
    67  	return nil, errUnsupportedEllipticCurve
    68  }
    69  
    70  func unmarshalEcPoint(curve elliptic.Curve, ecPoint []byte) (*big.Int, *big.Int, error) {
    71  	if len(ecPoint) < 64 {
    72  		return nil, nil, errors.New("invalid ecPoint length")
    73  	}
    74  	z, x, y := big.NewInt(0), big.NewInt(0), big.NewInt(0)
    75  	if len(ecPoint) != 64 {
    76  		x, y = elliptic.Unmarshal(curve, ecPoint)
    77  		if x == nil {
    78  			// http://docs.oasis-open.org/pkcs11/pkcs11-curr/v2.40/os/pkcs11-curr-v2.40-os.html#_ftn1
    79  			// PKCS#11 v2.20 specified that the CKA_EC_POINT was to be store in a DER-encoded
    80  			// OCTET STRING.
    81  			var rawEcPoint asn1.RawValue
    82  			if _, err := asn1.Unmarshal(ecPoint, &rawEcPoint); err == nil {
    83  				if len(rawEcPoint.Bytes) > 0 {
    84  					x, y = elliptic.Unmarshal(curve, rawEcPoint.Bytes)
    85  				}
    86  			}
    87  		}
    88  		if x == nil {
    89  			if byte(0x04) == ecPoint[0] && byte(0x04) == ecPoint[2] {
    90  				x, y = elliptic.Unmarshal(curve, ecPoint[2:])
    91  				if x == nil {
    92  					var point = ecPoint[3:]
    93  					x.SetBytes(point[:len(point)/2])
    94  					y.SetBytes(point[len(point)/2:])
    95  				}
    96  			}
    97  		}
    98  	} else {
    99  		x.SetBytes(ecPoint[:len(ecPoint)/2])
   100  		y.SetBytes(ecPoint[len(ecPoint)/2:])
   101  	}
   102  
   103  	if x.Cmp(z) == 0 || y.Cmp(z) == 0 {
   104  		return nil, nil, errors.New("ecPoint not a valid ecdsa or sm2 public key point")
   105  	}
   106  	return x, y, nil
   107  }