DES3 Key

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

des3.go

package main  
import (  
 "bytes"  
 "crypto/sha256"  
 "crypto/rand"  
 "encoding/base64"  
 "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()  
 // Create DES3 key  
 // first lookup the key  
 buf := new(bytes.Buffer)  
 var num uint16 = 1  
 err = binary.Write(buf, binary.LittleEndian, num)  
 if err != nil {  
 fmt.Println("binary.Write failed:", err)  
 }  
 id := buf.Bytes()  
 desKeyTemplate := []*pkcs11.Attribute{  
 pkcs11.NewAttribute(pkcs11.CKA_CLASS, pkcs11.CKO_SECRET_KEY),  
 pkcs11.NewAttribute(pkcs11.CKA_KEY_TYPE, pkcs11.CKK_DES3),  
 pkcs11.NewAttribute(pkcs11.CKA_ENCRYPT, true),  
 pkcs11.NewAttribute(pkcs11.CKA_DECRYPT, true),  
 pkcs11.NewAttribute(pkcs11.CKA_TOKEN, true),  
 pkcs11.NewAttribute(pkcs11.CKA_EXTRACTABLE, true), // we don't   
need to extract this..  
 pkcs11.NewAttribute(pkcs11.CKA_SENSITIVE, true),  
 pkcs11.NewAttribute(pkcs11.CKA_LABEL, "DESKey"), /*   
Name of Key */
}

 desKey, err := p.GenerateKey(session,  
   
[]*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_DES3_KEY_GEN , nil)},  
 desKeyTemplate)  
 if err != nil {  
 panic(fmt.Sprintf("GenerateKey() failed %s\n", err))  
 }  
 log.Printf("Created DES3 Key: %v", desKey)  
 ktemplate := []*pkcs11.Attribute{  
 pkcs11.NewAttribute(pkcs11.CKA_CLASS, pkcs11.CKO_SECRET_KEY),  
 pkcs11.NewAttribute(pkcs11.CKA_ID, id),  
 pkcs11.NewAttribute(pkcs11.CKA_LABEL, "DESKey"),  
 }  
 if err := p.FindObjectsInit(session, ktemplate); err != nil {  
 panic(err)  
 }  
 aesKeyTemplate := []*pkcs11.Attribute{  
 pkcs11.NewAttribute(pkcs11.CKA_CLASS, pkcs11.CKO_SECRET_KEY),  
 pkcs11.NewAttribute(pkcs11.CKA_KEY_TYPE, pkcs11.CKK_AES),  
 pkcs11.NewAttribute(pkcs11.CKA_ENCRYPT, true),  
 pkcs11.NewAttribute(pkcs11.CKA_DECRYPT, true),  
 pkcs11.NewAttribute(pkcs11.CKA_DECRYPT, true),  
 pkcs11.NewAttribute(pkcs11.CKA_WRAP, true),  
 pkcs11.NewAttribute(pkcs11.CKA_UNWRAP, true),  
 pkcs11.NewAttribute(pkcs11.CKA_TOKEN, true),  
 pkcs11.NewAttribute(pkcs11.CKA_EXTRACTABLE, true), // we don't   
need to extract this..  
 pkcs11.NewAttribute(pkcs11.CKA_SENSITIVE, true),  
 pkcs11.NewAttribute(pkcs11.CKA_VALUE_LEN, 32), /* KeyLength */  
 pkcs11.NewAttribute(pkcs11.CKA_LABEL, "AESKeyToWrap"), /*   
Name of Key */  
 }  
 aesKey, err := p.GenerateKey(session,  
 []*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_AES_KEY_GEN   
, nil)},
aesKeyTemplate)  
 if err != nil {  
 panic(fmt.Sprintf("GenerateKey() failed %s\n", err))  
 }  
 log.Printf("Created AES Key: %v", aesKey)  
 // Wrapping  
 wrappedPrivBytes, err := p.WrapKey(session,   
[]*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_DES3_CBC, nil)}, desKey,   
aesKey)  
 buf = new(bytes.Buffer)  
 num = 6  
 err = binary.Write(buf, binary.LittleEndian, num)  
 if err != nil {  
 log.Fatalf("binary.Write failed: %v", err)  
 }  
 importedPrivID := buf.Bytes()  
 aesKeyTemplate = []*pkcs11.Attribute{  
 pkcs11.NewAttribute(pkcs11.CKA_CLASS, pkcs11.CKO_SECRET_KEY),  
 pkcs11.NewAttribute(pkcs11.CKA_KEY_TYPE, pkcs11.CKK_AES),  
 pkcs11.NewAttribute(pkcs11.CKA_TOKEN, true),  
 pkcs11.NewAttribute(pkcs11.CKA_LABEL, "UnwrappedDES3Key"), /*   
Name of Key */  
 pkcs11.NewAttribute(pkcs11.CKA_ID, importedPrivID),  
 }  
 // Unwrapping   
ik, err := p.UnwrapKey(session,   
[]*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_DES3_CBC, nil)}, desKey,   
wrappedPrivBytes, aesKeyTemplate)  
 _ = ik  
 if err != nil {  
 log.Fatalf("Unwrap Failed: %v", err)  
 }  
 if err != nil {  
 log.Fatalf("failed to wrap privatekey : %s\n", err)  
 }  
 if err != nil {
 panic(err)  
 }  
 if err = p.FindObjectsFinal(session); err != nil {  
 panic(err)  
 }  
 iv := make([]byte, 8)  
 _, err = rand.Read(iv)  
 if err != nil {  
 panic(err)  
 }  
 // Encryption  
 err = p.EncryptInit(session,   
[]*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_DES3_CBC, iv)}, desKey )  
 if err != nil {  
 panic(fmt.Sprintf("EncryptInit() failed %s\n", err))  
 }  
 ct, err := p.Encrypt(session, []byte("fooooooo"))  
 if err != nil {  
 panic(fmt.Sprintf("Encrypt() failed %s\n", err))  
 }  
 // append the IV to the ciphertext  
 cdWithIV := append(iv, ct...)  
 log.Printf("Encrypted IV+Ciphertext %s",   
base64.RawStdEncoding.EncodeToString(cdWithIV))  
 // Decryption  
err = p.DecryptInit(session,   
[]*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_DES3_CBC, cdWithIV[0:8])},   
desKey)  
 if err != nil {  
 panic(fmt.Sprintf("EncryptInit() failed %s\n", err))  
 }  
 pt, err := p.Decrypt(session, ct[:8])  
 if err != nil {
 panic(fmt.Sprintf("Encrypt() failed %s\n", err))  
 }  
 log.Printf("Decrypt %s", string(pt))  
 // Signing  
 msg := []byte("foo")  
 digest := sha256.Sum256(msg)  
 log.Printf("Decrypt %s", string(pt))  
 err = p.SignInit(session,   
[]*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_DES3_CBC, nil)}, desKey)  
 sig, err := p.Sign(session, msg)  
 // Verification  
 err = p.VerifyInit(session,   
[]*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_DES3_CBC, nil)}, desKey)  
 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 des3.go 
  1. Verify that keys are generated on HSM using below command.

›_ Console

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

List keys