AES Key

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

aes.go

package main  
import (  
 "bytes"  
 "crypto/rand"  
 "crypto/sha256"  
 "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 AES 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()  
 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_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, "AESKey"), /*   
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)  
 ktemplate := []*pkcs11.Attribute{  
 pkcs11.NewAttribute(pkcs11.CKA_CLASS, pkcs11.CKO_SECRET_KEY),  
 pkcs11.NewAttribute(pkcs11.CKA_ID, id),  
 pkcs11.NewAttribute(pkcs11.CKA_LABEL, "AESKey"),  
 }  
 aesKeyTemplate2 := []*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 */  
 }  
 aesKey2, err := p.GenerateKey(session,  
 []*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_AES_KEY_GEN   
, nil)},  
 aesKeyTemplate2)  
 if err != nil {
 panic(fmt.Sprintf("GenerateKey() failed %s\n", err))  
 }  
 log.Printf("Created AES Key: %v", aesKey2)  
 if err := p.FindObjectsInit(session, ktemplate); err != nil {  
 panic(err)  
 }  
 if err != nil {  
 panic(err)  
 }  
 if err = p.FindObjectsFinal(session); err != nil {  
 panic(err)  
 }  
 iv := make([]byte, 16)  
 _, err = rand.Read(iv)  
 if err != nil {  
 panic(err)  
 }  
 // Encryption  
 err = p.EncryptInit(session,   
[]*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_AES_CBC_PAD, iv)}, aesKey)  
 if err != nil {  
 panic(fmt.Sprintf("EncryptInit() failed %s\n", err))  
 }  
   
   
 ct, err := p.Encrypt(session, []byte("foo"))  
 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_AES_CBC_PAD,   
cdWithIV[0:16])}, aesKey)  
 if err != nil {  
 panic(fmt.Sprintf("EncryptInit() failed %s\n", err))  
 }  
 pt, err := p.Decrypt(session, ct[:16])  
 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_AES_CBC, nil)}, aesKey)  
   
 sig, err := p.Sign(session, msg)  
 // Verification  
 err = p.VerifyInit(session,   
[]*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_AES_CBC, nil)}, aesKey)  
 err = p.Verify(session, digest[:], sig)  
 // Wrapping  
 wrappedPrivBytes, err := p.WrapKey(session,   
[]*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_AES_KEY_WRAP, nil)},   
aesKey, aesKey2)  
 if err != nil {  
 log.Fatalf("failed to wrap privatekey : %s\n", err)  
 }  
 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()  
 aesKeyTemplate2 = []*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, "UnwrappedAESKey"), /*   
Name of Key */  
 pkcs11.NewAttribute(pkcs11.CKA_ID, importedPrivID),  
 }  
 // Unwrapping  
 ik, err := p.UnwrapKey(session,   
[]*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_AES_KEY_WRAP, nil)},   
aesKey, wrappedPrivBytes, aesKeyTemplate2)  
 _ = ik  
 if err != nil {  
 log.Fatalf("Unwrap Failed: %v", err)  
 }  
}  

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

  1. Execute the go code using the command below.

›_ Console

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

›_ Console

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

List keys