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 }