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 }