gitee.com/lh-her-team/common@v1.5.1/crypto/pkcs11/curve.go (about)

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