From f689e1a7f346b7b6299dbd23af06d56feca0c79f Mon Sep 17 00:00:00 2001 From: Andy Doan Date: Thu, 25 Jun 2020 20:35:05 -0500 Subject: [PATCH] ecdsa: Add support for ECDH1-DERIVE method This method can be used to help do ecies encryption. Signed-off-by: Andy Doan --- ecdsa.go | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/ecdsa.go b/ecdsa.go index c094232..8b49ae8 100644 --- a/ecdsa.go +++ b/ecdsa.go @@ -300,3 +300,44 @@ func (c *Context) GenerateECDSAKeyPairWithAttributes(public, private AttributeSe func (signer *pkcs11PrivateKeyECDSA) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) ([]byte, error) { return signer.context.dsaGeneric(signer.handle, pkcs11.CKM_ECDSA, digest) } + +// Perform CKM_ECDH1_DERIVE function with the given public key +func (c *Context) ECDH1Derive(pk Signer, pubkey *ecdsa.PublicKey) ([]byte, error) { + ecpk := pk.(*pkcs11PrivateKeyECDSA) + + template := []*pkcs11.Attribute{ + pkcs11.NewAttribute(pkcs11.CKA_TOKEN, false), + pkcs11.NewAttribute(pkcs11.CKA_CLASS, pkcs11.CKO_SECRET_KEY), + pkcs11.NewAttribute(pkcs11.CKA_KEY_TYPE, pkcs11.CKK_GENERIC_SECRET), + pkcs11.NewAttribute(pkcs11.CKA_SENSITIVE, false), + pkcs11.NewAttribute(pkcs11.CKA_EXTRACTABLE, true), + pkcs11.NewAttribute(pkcs11.CKA_ENCRYPT, true), + pkcs11.NewAttribute(pkcs11.CKA_DECRYPT, true), + pkcs11.NewAttribute(pkcs11.CKA_WRAP, true), + pkcs11.NewAttribute(pkcs11.CKA_UNWRAP, true), + pkcs11.NewAttribute(pkcs11.CKA_VALUE_LEN, (pubkey.Curve.Params().BitSize + 7) / 8), + } + params := pkcs11.ECDH1DeriveParams{KDF: pkcs11.CKD_NULL, PublicKeyData: elliptic.Marshal(pubkey.Curve, pubkey.X, pubkey.Y)} + mech := []*pkcs11.Mechanism{ + pkcs11.NewMechanism(pkcs11.CKM_ECDH1_DERIVE, ¶ms), + } + + var buf []byte + err := c.withSession(func(session *pkcs11Session) error { + handle, err := session.ctx.DeriveKey(session.handle, mech, ecpk.handle, template) + if err != nil { + return err + } + + template = []*pkcs11.Attribute{ + pkcs11.NewAttribute(pkcs11.CKA_VALUE, nil), + } + attr, err := session.ctx.GetAttributeValue(session.handle, handle, template) + if err != nil { + return err + } + buf = attr[0].Value + return nil + }) + return buf, err +}