ECC Key

  1. Create a ecckey.go file and add the contents as shown below.

ecckey.go

# package main  
import (  
 "bytes"  
 "crypto/sha256"  
 "encoding/binary"  
 "fmt"  
 "log"  
 "github.com/miekg/pkcs11"  
)  
const (  
 pin = "87654321"  
)  
var ()  
func main() {  
 // Init PKCS11  
 p := pkcs11.New("/opt/utimaco/lib/libcs_pkcs11_R3.so")  
 err := p.Initialize()  
 if err != nil {  
 panic(err)  
 }  
 defer p.Destroy()  
 defer p.Finalize()  
 slots, err := p.GetSlotList(true)  
 if err != nil {  
 panic(err)  
 }  
 session, err := p.OpenSession(slots[0],   
pkcs11.CKF_SERIAL_SESSION|pkcs11.CKF_RW_SESSION)
if err != nil {  
 panic(err)  
 }  
 defer p.CloseSession(session)  
 err = p.Login(session, pkcs11.CKU_USER, pin)  
 if err != nil {  
 panic(err)  
 }  
 defer p.Logout(session)  
 info, err := p.GetInfo()  
 if err != nil {  
 panic(err)  
 }  
 fmt.Printf("CryptokiVersion.Major %v", info.CryptokiVersion.Major)  
 fmt.Println()  
 buf := new(bytes.Buffer)  
 buf = new(bytes.Buffer)  
 var num uint16 = 1  
 num = 1  
 err = binary.Write(buf, binary.LittleEndian, num)  
 if err != nil {  
 log.Fatalf("binary.Write failed: %v", err)  
 }  
 pubID := buf.Bytes()  
 buf = new(bytes.Buffer)  
 num = 2  
 err = binary.Write(buf, binary.LittleEndian, num)  
 if err != nil {  
 log.Fatalf("binary.Write failed: %v", err)  
 }  
 privID := buf.Bytes()  
 publicKeyTemplate := []*pkcs11.Attribute{  
 pkcs11.NewAttribute(pkcs11.CKA_CLASS, pkcs11.CKO_PUBLIC_KEY),  
 pkcs11.NewAttribute(pkcs11.CKA_KEY_TYPE, pkcs11.CKK_ECDSA),  
 pkcs11.NewAttribute(pkcs11.CKA_TOKEN, true),  
 pkcs11.NewAttribute(pkcs11.CKA_VERIFY, true),  
 pkcs11.NewAttribute(pkcs11.CKA_PRIVATE, true),
 pkcs11.NewAttribute(pkcs11.CKA_ENCRYPT, true),  
 pkcs11.NewAttribute(pkcs11.CKA_WRAP, false),  
 pkcs11.NewAttribute(pkcs11.CKA_LABEL, "pub1"),  
 pkcs11.NewAttribute(pkcs11.CKA_ID, pubID),  
 pkcs11.NewAttribute(pkcs11.CKA_EC_PARAMS, []byte{0x06, 0x08,   
0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07}),  
 }  
 privateKeyTemplate := []*pkcs11.Attribute{  
 pkcs11.NewAttribute(pkcs11.CKA_CLASS, pkcs11.CKO_PRIVATE_KEY),  
 pkcs11.NewAttribute(pkcs11.CKA_KEY_TYPE, pkcs11.CKK_ECDSA),  
 pkcs11.NewAttribute(pkcs11.CKA_TOKEN, true),  
 pkcs11.NewAttribute(pkcs11.CKA_SIGN, true),  
 pkcs11.NewAttribute(pkcs11.CKA_DECRYPT, true),  
 pkcs11.NewAttribute(pkcs11.CKA_LABEL, "priv1"),  
 pkcs11.NewAttribute(pkcs11.CKA_PRIVATE, true),  
 pkcs11.NewAttribute(pkcs11.CKA_SENSITIVE, true),  
 pkcs11.NewAttribute(pkcs11.CKA_WRAP_WITH_TRUSTED, false),  
 pkcs11.NewAttribute(pkcs11.CKA_UNWRAP, false),  
 pkcs11.NewAttribute(pkcs11.CKA_EXTRACTABLE, false),  
 pkcs11.NewAttribute(pkcs11.CKA_ID, privID),  
 }  
 pbk, pvk, err := p.GenerateKeyPair(session,  
   
[]*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_ECDSA_KEY_PAIR_GEN, nil)},  
 publicKeyTemplate, privateKeyTemplate)  
 _ = pvk  
 _ = pbk  
 if err != nil {  
 log.Fatalf("failed to generate exportable keypair: %s\n", err)  
 }  
 // Signing  
 msg := []byte("foo")  
 digest := sha256.Sum256(msg)  
 err = p.SignInit(session,   
[]*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_ECDSA_SHA1, nil)}, pvk)  
 sig, err := p.Sign(session, msg)  
 // Verification
  err = p.VerifyInit(session,   
[]*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_ECDSA_SHA1, nil)}, pbk)  
 err = p.Verify(session, digest[:], sig)  
}  

Update Slot PIN and PKCS#11 library path according to your environment.

  1. Execute the go code using the command below.

›_ Console

# go run ecckey.go 
  1. Verify that keys are generated on HSM using below command.

›_ Console

# p11tool2 Slot=<slot_no.> LoginUser=ask ListObjects 
image-3284566252-1.jpg

List keys

This completes the Integration for GO PKCS#11 Wrapper with Utimaco SecurityServer.