examples

package
v0.0.0-...-6cdb20f Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 18, 2022 License: Apache-2.0 Imports: 0 Imported by: 0

Documentation

Overview

Package examples provide GREP11 function call examples. Regular function calls have four steps. The following is one example to generate a key:

1 cryptoClient := pb.NewCryptoClient(conn) // create a crypto client 2 Template := util.NewAttributeMap // create a template 3 keygenmsg, err := &pb.GenerateKeyRequest() // create RPC request parameters 4 if err != nill {...} // check for an error

Example (Bip32DeriveKey)
conn, err := grpc.Dial(address, callOpts...)
if err != nil {
	panic(fmt.Errorf("Could not connect to server: %s", err))
}
defer conn.Close()
cryptoClient := pb.NewCryptoClient(conn)

generateKeyRequest := &pb.GenerateKeyRequest{
	Mech: &pb.Mechanism{Mechanism: ep11.CKM_GENERIC_SECRET_KEY_GEN},
	Template: util.AttributeMap(
		ep11.EP11Attributes{
			ep11.CKA_KEY_TYPE:        ep11.CKK_GENERIC_SECRET,
			ep11.CKA_CLASS:           ep11.CKO_SECRET_KEY,
			ep11.CKA_VALUE_LEN:       (uint64)(256 / 8),
			ep11.CKA_WRAP:            false,
			ep11.CKA_UNWRAP:          false,
			ep11.CKA_SIGN:            true,
			ep11.CKA_VERIFY:          true,
			ep11.CKA_EXTRACTABLE:     false,
			ep11.CKA_DERIVE:          true,
			ep11.CKA_IBM_USE_AS_DATA: true,
		},
	),
}
generateKeyResponse, err := cryptoClient.GenerateKey(context.Background(), generateKeyRequest)
if err != nil {
	panic(fmt.Errorf("Generated Generic Secret Key error: %+v %s", generateKeyRequest, err))
} else {
	fmt.Println("Generated Generic Secret Key")
}
masterSecretKey, masterChainCode := bip32_deriveKey(
	cryptoClient,
	pb.BTCDeriveParm_CkBIP0032MASTERK,
	0,
	generateKeyResponse.KeyBytes,
	nil,
)

const maxDepth = 3
const maxChild = 3
var privateKey [maxDepth][maxChild][]byte
var privateChainCode [maxDepth][maxChild][]byte
var publicKey [maxDepth][maxChild][]byte
var publicChainCode [maxDepth][maxChild][]byte
var child, depth uint64

for child = 0; child < maxChild; child++ {
	privateKey[0][child], privateChainCode[0][child] = bip32_deriveKey(
		cryptoClient,
		pb.BTCDeriveParm_CkBIP0032PRV2PRV,
		child,
		masterSecretKey,
		masterChainCode,
	)
	publicKey[0][child], publicChainCode[0][child] = bip32_deriveKey(
		cryptoClient,
		pb.BTCDeriveParm_CkBIP0032PRV2PUB,
		child,
		masterSecretKey,
		masterChainCode,
	)
}
for depth = 1; depth < maxDepth; depth++ {
	for child = 0; child < maxChild; child++ {
		privateKey[depth][child], privateChainCode[depth][child] = bip32_deriveKey(
			cryptoClient,
			pb.BTCDeriveParm_CkBIP0032PRV2PRV,
			child,
			privateKey[depth-1][child],
			privateChainCode[depth-1][child],
		)
		publicKey[depth][child], publicChainCode[depth][child] = bip32_deriveKey(
			cryptoClient,
			pb.BTCDeriveParm_CkBIP0032PRV2PUB,
			child,
			privateKey[depth-1][child],
			privateChainCode[depth-1][child],
		)
		// PUB2PUB is not supported yet
		/*
		   publicKey[depth][child], publicChainCode[depth][child] = bip32_deriveKey(
		       cryptoClient,
		       pb.BTCDeriveParm_CkBIP0032PUB2PUB,
		       child,
		       publicKey[depth-1][child],
		       publicChainCode[depth-1][child],
		   )
		*/ )
		*/
	}
}
for depth = 0; depth < maxDepth; depth++ {
	for child = 0; child < maxChild; child++ {
		bip32_signAndVerifySingle(cryptoClient, privateKey[depth][child], publicKey[depth][child])
	}
}
Output:

Generated Generic Secret Key
Derived Key type=CkBIP0032MASTERK index=0
Derived Key type=CkBIP0032PRV2PRV index=0
Derived Key type=CkBIP0032PRV2PUB index=0
Derived Key type=CkBIP0032PRV2PRV index=1
Derived Key type=CkBIP0032PRV2PUB index=1
Derived Key type=CkBIP0032PRV2PRV index=2
Derived Key type=CkBIP0032PRV2PUB index=2
Derived Key type=CkBIP0032PRV2PRV index=0
Derived Key type=CkBIP0032PRV2PUB index=0
Derived Key type=CkBIP0032PRV2PRV index=1
Derived Key type=CkBIP0032PRV2PUB index=1
Derived Key type=CkBIP0032PRV2PRV index=2
Derived Key type=CkBIP0032PRV2PUB index=2
Derived Key type=CkBIP0032PRV2PRV index=0
Derived Key type=CkBIP0032PRV2PUB index=0
Derived Key type=CkBIP0032PRV2PRV index=1
Derived Key type=CkBIP0032PRV2PUB index=1
Derived Key type=CkBIP0032PRV2PRV index=2
Derived Key type=CkBIP0032PRV2PUB index=2
Data signed
Signature verified
Data signed
Signature verified
Data signed
Signature verified
Data signed
Signature verified
Data signed
Signature verified
Data signed
Signature verified
Data signed
Signature verified
Data signed
Signature verified
Data signed
Signature verified
Example (Bip32_Base)

general tests cases

conn, err := grpc.Dial(address, callOpts...)
if err != nil {
	panic(fmt.Errorf("Could not connect to server: %s", err))
}
defer conn.Close()
cryptoClient := pb.NewCryptoClient(conn)

fmt.Printf("Generating random seed key...\n")
generateKeyRequest := &pb.GenerateKeyRequest{
	Mech: &pb.Mechanism{Mechanism: ep11.CKM_GENERIC_SECRET_KEY_GEN},
	Template: util.AttributeMap(
		ep11.EP11Attributes{
			ep11.CKA_KEY_TYPE:        ep11.CKK_GENERIC_SECRET,
			ep11.CKA_CLASS:           ep11.CKO_SECRET_KEY,
			ep11.CKA_VALUE_LEN:       (uint64)(256 / 8),
			ep11.CKA_WRAP:            false,
			ep11.CKA_UNWRAP:          false,
			ep11.CKA_SIGN:            true,
			ep11.CKA_VERIFY:          true,
			ep11.CKA_EXTRACTABLE:     false,
			ep11.CKA_DERIVE:          true,
			ep11.CKA_IBM_USE_AS_DATA: true,
		},
	),
}
generateKeyResponse, err := cryptoClient.GenerateKey(context.Background(), generateKeyRequest)
if err != nil {
	panic(fmt.Errorf("Generated Generic Secret Key error: %+v %s", generateKeyRequest, err))
}
const max_depth = 3
const max_child = 1

var privateKey [max_depth][max_child][]byte
var privateChainCode [max_depth][max_child][]byte
var publicKey [max_depth][max_child][]byte
var publicChainCode [max_depth][max_child][]byte
var child, depth uint64

fmt.Println("Depth0: Generating master key and master chaincode...")
masterSecretKey, masterChainCode := bip32_deriveKey(
	cryptoClient,
	pb.BTCDeriveParm_CkBIP0032MASTERK,
	0,
	generateKeyResponse.KeyBytes,
	nil,
)
fmt.Println("Depth0: Generated master key from random seed and master chaincode")

fmt.Println("Depth1: Generating Wallets accounts...")
privateKey[0][0], privateChainCode[0][0] = bip32_deriveKey(
	cryptoClient,
	pb.BTCDeriveParm_CkBIP0032PRV2PRV,
	0,
	masterSecretKey,
	masterChainCode,
)
publicKey[0][0], publicChainCode[0][0] = bip32_deriveKey(
	cryptoClient,
	pb.BTCDeriveParm_CkBIP0032PRV2PUB,
	0,
	masterSecretKey,
	masterChainCode,
)

fmt.Println("Depth1: Generated external and internal Wallet accout")

fmt.Println("Depth2: Generating Wallets chains...")
privateKey[1][0], privateChainCode[1][0] = bip32_deriveKey(
	cryptoClient,
	pb.BTCDeriveParm_CkBIP0032PRV2PRV,
	0,
	privateKey[0][0],
	privateChainCode[0][0],
)
publicKey[1][0], publicChainCode[1][0] = bip32_deriveKey(
	cryptoClient,
	pb.BTCDeriveParm_CkBIP0032PRV2PUB,
	0,
	privateKey[0][0],
	privateChainCode[0][0],
)

fmt.Println("Depth2: Generated internal and external wallet chain successfully")

fmt.Println("Depth3: Generating Wallets addresses...")
privateKey[2][0], privateChainCode[2][0] = bip32_deriveKey(
	cryptoClient,
	pb.BTCDeriveParm_CkBIP0032PRV2PRV,
	0,
	privateKey[1][0],
	privateChainCode[1][0],
)
publicKey[2][0], publicChainCode[2][0] = bip32_deriveKey(
	cryptoClient,
	pb.BTCDeriveParm_CkBIP0032PRV2PUB,
	0,
	privateKey[1][0],
	privateChainCode[1][0],
)
fmt.Println("Depth3: Generated external and internal addresses successfully.")

for depth = 0; depth < max_depth; depth++ {
	for child = 0; child < max_child; child++ {
		bip32_signAndVerify(cryptoClient, privateKey[depth][child], publicKey[depth][child])
	}
}
fmt.Println("Sign and verify")

for depth = 0; depth < max_depth; depth++ {
	for child = 0; child < max_child; child++ {
		bip32_signAndVerifySingle(cryptoClient, privateKey[depth][child], publicKey[depth][child])
	}
}
fmt.Println("SignSingle and verifySingle")
Output:

Generating random seed key...
Depth0: Generating master key and master chaincode...
Derived Key type=CkBIP0032MASTERK index=0
Depth0: Generated master key from random seed and master chaincode
Depth1: Generating Wallets accounts...
Derived Key type=CkBIP0032PRV2PRV index=0
Derived Key type=CkBIP0032PRV2PUB index=0
Depth1: Generated external and internal Wallet accout
Depth2: Generating Wallets chains...
Derived Key type=CkBIP0032PRV2PRV index=0
Derived Key type=CkBIP0032PRV2PUB index=0
Depth2: Generated internal and external wallet chain successfully
Depth3: Generating Wallets addresses...
Derived Key type=CkBIP0032PRV2PRV index=0
Derived Key type=CkBIP0032PRV2PUB index=0
Depth3: Generated external and internal addresses successfully.
Data signed
Signature verified
Data signed
Signature verified
Data signed
Signature verified
Sign and verify
Data signed
Signature verified
Data signed
Signature verified
Data signed
Signature verified
SignSingle and verifySingle
Example (Bip32_Cross_SignVerify)

cross sign and verification

conn, err := grpc.Dial(address, callOpts...)
if err != nil {
	panic(fmt.Errorf("Could not connect to server: %s", err))
}
defer conn.Close()
cryptoClient := pb.NewCryptoClient(conn)

fmt.Printf("Generating random seed key...\n")
generateKeyRequest := &pb.GenerateKeyRequest{
	Mech: &pb.Mechanism{Mechanism: ep11.CKM_GENERIC_SECRET_KEY_GEN},
	Template: util.AttributeMap(
		ep11.EP11Attributes{
			ep11.CKA_KEY_TYPE:        ep11.CKK_GENERIC_SECRET,
			ep11.CKA_CLASS:           ep11.CKO_SECRET_KEY,
			ep11.CKA_VALUE_LEN:       (uint64)(256 / 8),
			ep11.CKA_WRAP:            false,
			ep11.CKA_UNWRAP:          false,
			ep11.CKA_SIGN:            true,
			ep11.CKA_VERIFY:          true,
			ep11.CKA_EXTRACTABLE:     false,
			ep11.CKA_DERIVE:          true,
			ep11.CKA_IBM_USE_AS_DATA: true,
		},
	),
}
generateKeyResponse, err := cryptoClient.GenerateKey(context.Background(), generateKeyRequest)
if err != nil {
	panic(fmt.Errorf("Generated Generic Secret Key error: %+v %s", generateKeyRequest, err))
}

fmt.Println("Generating master key and master chaincode...")
masterSecretKey, masterChainCode := bip32_deriveKey(
	cryptoClient,
	pb.BTCDeriveParm_CkBIP0032MASTERK,
	0,
	generateKeyResponse.KeyBytes,
	nil,
)
fmt.Println("Generated master key from random seed and master chaincode")

var privateKey_w [3][]byte
var privateChainCode_w [3][]byte
var publicKey_w [3][]byte
var publicChainCode_w [3][]byte

privateKey_w[0], privateChainCode_w[0] = bip32_deriveKey(
	cryptoClient,
	pb.BTCDeriveParm_CkBIP0032PRV2PRV,
	0,
	masterSecretKey,
	masterChainCode,
)
publicKey_w[0], publicChainCode_w[0] = bip32_deriveKey(
	cryptoClient,
	pb.BTCDeriveParm_CkBIP0032PRV2PUB,
	0,
	masterSecretKey,
	masterChainCode,
)
fmt.Println("Depth1: Generated external and internal Wallet accout")
bip32_signAndVerifySingle(cryptoClient, privateKey_w[0], publicKey_w[0])

privateKey_w[1], privateChainCode_w[1] = bip32_deriveKey(
	cryptoClient,
	pb.BTCDeriveParm_CkBIP0032PRV2PRV,
	0,
	privateKey_w[0],
	privateChainCode_w[0],
)
publicKey_w[1], publicChainCode_w[1] = bip32_deriveKey(
	cryptoClient,
	pb.BTCDeriveParm_CkBIP0032PRV2PUB,
	0,
	privateKey_w[0],
	privateChainCode_w[0],
)
fmt.Println("Depth2: Generated internal and external wallet chain successfully")
bip32_signAndVerifySingle(cryptoClient, privateKey_w[1], publicKey_w[1])

privateKey_w[2], privateChainCode_w[2] = bip32_deriveKey(
	cryptoClient,
	pb.BTCDeriveParm_CkBIP0032PRV2PRV,
	0,
	privateKey_w[1],
	privateChainCode_w[1],
)
publicKey_w[2], publicChainCode_w[2] = bip32_deriveKey(
	cryptoClient,
	pb.BTCDeriveParm_CkBIP0032PRV2PUB,
	0,
	privateKey_w[1],
	privateChainCode_w[1],
)
fmt.Println("Depth3: Generated external and internal addresses successfully.")
bip32_signAndVerifySingle(cryptoClient, privateKey_w[2], publicKey_w[2])

fmt.Println("Round 1: Cross verification")
signData_1 := sha256.New().Sum([]byte("This data needs to be signed"))
signSingleRequest_1 := &pb.SignSingleRequest{
	Mech:    &pb.Mechanism{Mechanism: ep11.CKM_ECDSA},
	PrivKey: privateKey_w[2],
	Data:    signData_1,
}
signSingleResponse_1, err := cryptoClient.SignSingle(context.Background(), signSingleRequest_1)
if err != nil {
	panic(fmt.Errorf("SignSingle error: %s", err))
}

verifySingleRequest_1 := &pb.VerifySingleRequest{
	Mech:      &pb.Mechanism{Mechanism: ep11.CKM_ECDSA},
	PubKey:    publicKey_w[1],
	Data:      signData_1,
	Signature: signSingleResponse_1.Signature,
}
_, err = cryptoClient.VerifySingle(context.Background(), verifySingleRequest_1)
if ok, ep11Status := util.Convert(err); !ok {
	if ep11Status.Code == ep11.CKR_SIGNATURE_INVALID {
		fmt.Println("Round 1: Invalid signature")
	} else {
		panic(fmt.Errorf("Verify error: [%d]: %s", ep11Status.Code, ep11Status.Detail))
	}
}

fmt.Println("Round 2: Cross verification")
signData_2 := sha256.New().Sum([]byte("This data needs to be signed"))
signSingleRequest_2 := &pb.SignSingleRequest{
	Mech:    &pb.Mechanism{Mechanism: ep11.CKM_ECDSA},
	PrivKey: privateKey_w[1],
	Data:    signData_2,
}
signSingleResponse_2, err := cryptoClient.SignSingle(context.Background(), signSingleRequest_2)
if err != nil {
	panic(fmt.Errorf("SignSingle error: %s", err))
}

verifySingleRequest_2 := &pb.VerifySingleRequest{
	Mech:      &pb.Mechanism{Mechanism: ep11.CKM_ECDSA},
	PubKey:    publicKey_w[0],
	Data:      signData_2,
	Signature: signSingleResponse_2.Signature,
}
_, err = cryptoClient.VerifySingle(context.Background(), verifySingleRequest_2)
if ok, ep11Status := util.Convert(err); !ok {
	if ep11Status.Code == ep11.CKR_SIGNATURE_INVALID {
		fmt.Println("Round 2: Invalid signature")
	} else {
		panic(fmt.Errorf("Verify error: [%d]: %s", ep11Status.Code, ep11Status.Detail))
	}
}

fmt.Println("Round 3: Cross verification")
signData_3 := sha256.New().Sum([]byte("This data needs to be signed"))
signSingleRequest_3 := &pb.SignSingleRequest{
	Mech:    &pb.Mechanism{Mechanism: ep11.CKM_ECDSA},
	PrivKey: privateKey_w[0],
	Data:    signData_3,
}
signSingleResponse_3, err := cryptoClient.SignSingle(context.Background(), signSingleRequest_3)
if err != nil {
	panic(fmt.Errorf("SignSingle error: %s", err))
}

verifySingleRequest_3 := &pb.VerifySingleRequest{
	Mech:      &pb.Mechanism{Mechanism: ep11.CKM_ECDSA},
	PubKey:    publicKey_w[2],
	Data:      signData_3,
	Signature: signSingleResponse_3.Signature,
}
_, err = cryptoClient.VerifySingle(context.Background(), verifySingleRequest_3)
if ok, ep11Status := util.Convert(err); !ok {
	if ep11Status.Code == ep11.CKR_SIGNATURE_INVALID {
		fmt.Println("Round 3: Invalid signature")
	} else {
		panic(fmt.Errorf("Verify error: [%d]: %s", ep11Status.Code, ep11Status.Detail))
	}
}
Output:

Generating random seed key...
Generating master key and master chaincode...
Derived Key type=CkBIP0032MASTERK index=0
Generated master key from random seed and master chaincode
Derived Key type=CkBIP0032PRV2PRV index=0
Derived Key type=CkBIP0032PRV2PUB index=0
Depth1: Generated external and internal Wallet accout
Data signed
Signature verified
Derived Key type=CkBIP0032PRV2PRV index=0
Derived Key type=CkBIP0032PRV2PUB index=0
Depth2: Generated internal and external wallet chain successfully
Data signed
Signature verified
Derived Key type=CkBIP0032PRV2PRV index=0
Derived Key type=CkBIP0032PRV2PUB index=0
Depth3: Generated external and internal addresses successfully.
Data signed
Signature verified
Round 1: Cross verification
Round 1: Invalid signature
Round 2: Cross verification
Round 2: Invalid signature
Round 3: Cross verification
Round 3: Invalid signature
Example (Bip32_KeyDerivation)

cover private->private public->public key derivation

conn, err := grpc.Dial(address, callOpts...)
if err != nil {
	panic(fmt.Errorf("Could not connect to server: %s", err))
}
defer conn.Close()
cryptoClient := pb.NewCryptoClient(conn)

fmt.Printf("Generating random seed key...\n")
generateKeyRequest := &pb.GenerateKeyRequest{
	Mech: &pb.Mechanism{Mechanism: ep11.CKM_GENERIC_SECRET_KEY_GEN},
	Template: util.AttributeMap(
		ep11.EP11Attributes{
			ep11.CKA_KEY_TYPE:        ep11.CKK_GENERIC_SECRET,
			ep11.CKA_CLASS:           ep11.CKO_SECRET_KEY,
			ep11.CKA_VALUE_LEN:       (uint64)(256 / 8),
			ep11.CKA_WRAP:            false,
			ep11.CKA_UNWRAP:          false,
			ep11.CKA_SIGN:            true,
			ep11.CKA_VERIFY:          true,
			ep11.CKA_EXTRACTABLE:     false,
			ep11.CKA_DERIVE:          true,
			ep11.CKA_IBM_USE_AS_DATA: true,
		},
	),
}
generateKeyResponse, err := cryptoClient.GenerateKey(context.Background(), generateKeyRequest)
if err != nil {
	panic(fmt.Errorf("Generated Generic Secret Key error: %+v %s", generateKeyRequest, err))
}

var publicKey []byte
var publicChainCode []byte

fmt.Println("Generating master key and master chaincode...")
masterSecretKey, masterChainCode := bip32_deriveKey(
	cryptoClient,
	pb.BTCDeriveParm_CkBIP0032MASTERK,
	0,
	generateKeyResponse.KeyBytes,
	nil,
)
fmt.Println("Generated master key from random seed and master chaincode")

fmt.Println("Generating Wallets accounts...")
ecParameters, err := asn1.Marshal(util.OIDNamedCurveSecp256k1)
if err != nil {
	panic(fmt.Errorf("Unable to encode parameter OID: %s", err))
}
publicKey, publicChainCode = bip32_deriveKey(
	cryptoClient,
	pb.BTCDeriveParm_CkBIP0032PRV2PUB,
	0,
	masterSecretKey,
	masterChainCode,
)
fmt.Println("Derive key from private -> public")
deriveKeyRequestPri := &pb.DeriveKeyRequest{
	Mech: &pb.Mechanism{
		Mechanism: ep11.CKM_IBM_BTC_DERIVE,
		Parameter: &pb.Mechanism_BTCDeriveParameter{
			BTCDeriveParameter: &pb.BTCDeriveParm{
				Type:          pb.BTCDeriveParm_CkBIP0032PRV2PRV,
				ChildKeyIndex: 0,
				ChainCode:     masterChainCode,
				Version:       1,
			},
		},
	},
	Template: util.AttributeMap(
		ep11.EP11Attributes{
			ep11.CKA_VERIFY:          true,
			ep11.CKA_EXTRACTABLE:     false,
			ep11.CKA_DERIVE:          true,
			ep11.CKA_KEY_TYPE:        ep11.CKK_ECDSA,
			ep11.CKA_VALUE_LEN:       (uint64)(0),
			ep11.CKA_IBM_USE_AS_DATA: true,
			ep11.CKA_EC_PARAMS:       ecParameters,
		},
	),
	BaseKey: masterSecretKey,
}
_, err = cryptoClient.DeriveKey(context.Background(), deriveKeyRequestPri)
if err != nil {
	fmt.Println("Don't supporte deriving key from pulic to public in current soft-hsm version")
} else {
	fmt.Println("Derive key from private -> private")
}

deriveKeyRequestPub := &pb.DeriveKeyRequest{
	Mech: &pb.Mechanism{
		Mechanism: ep11.CKM_IBM_BTC_DERIVE,
		Parameter: &pb.Mechanism_BTCDeriveParameter{
			BTCDeriveParameter: &pb.BTCDeriveParm{
				Type:          pb.BTCDeriveParm_CkBIP0032PUB2PUB,
				ChildKeyIndex: 0,
				ChainCode:     publicChainCode,
				Version:       1,
			},
		},
	},
	Template: util.AttributeMap(
		ep11.EP11Attributes{
			ep11.CKA_VERIFY:          true,
			ep11.CKA_EXTRACTABLE:     false,
			ep11.CKA_DERIVE:          true,
			ep11.CKA_KEY_TYPE:        ep11.CKK_ECDSA,
			ep11.CKA_VALUE_LEN:       (uint64)(0),
			ep11.CKA_IBM_USE_AS_DATA: true,
			ep11.CKA_EC_PARAMS:       ecParameters,
		},
	),
	BaseKey: publicKey,
}
_, err = cryptoClient.DeriveKey(context.Background(), deriveKeyRequestPub)
if err != nil {
	fmt.Println("Don't supporte deriving key from pulic -> public in current soft-hsm version")
} else {
	fmt.Printf("Derive key from public to public successfully")
}
Output:

Generating random seed key...
Generating master key and master chaincode...
Derived Key type=CkBIP0032MASTERK index=0
Generated master key from random seed and master chaincode
Generating Wallets accounts...
Derived Key type=CkBIP0032PRV2PUB index=0
Derive key from private -> public
Derive key from private -> private
Derive key from public to public successfully
Example (Digest)

Example_digest calculates the digest of some plain text Flow: connect, digest single-part data, digest multi-part data

conn, err := grpc.Dial(address, callOpts...)
if err != nil {
	panic(fmt.Errorf("Could not connect to server: %s", err))
}
defer conn.Close()

cryptoClient := pb.NewCryptoClient(conn)

digestData := []byte("This is the data longer than 64 bytes This is the data longer than 64 bytes")
digestInitRequest := &pb.DigestInitRequest{
	Mech: &pb.Mechanism{Mechanism: ep11.CKM_SHA256},
}
digestInitResponse, err := cryptoClient.DigestInit(context.Background(), digestInitRequest)
if err != nil {
	panic(fmt.Errorf("Digest init error: %s", err))
}
digestRequest := &pb.DigestRequest{
	State: digestInitResponse.State,
	Data:  digestData,
}
digestResponse, err := cryptoClient.Digest(context.Background(), digestRequest)
if err != nil {
	panic(fmt.Errorf("Digest error: %s", err))
} else {
	fmt.Printf("Digest data using a single digest operation: %x\n", digestResponse.Digest)
}

// Digest using mutiple operations
digestInitResponse, err = cryptoClient.DigestInit(context.Background(), digestInitRequest)
if err != nil {
	panic(fmt.Errorf("Digest init error: %s", err))
}
digestUpdateRequest := &pb.DigestUpdateRequest{
	State: digestInitResponse.State,
	Data:  digestData[:64],
}
digestUpdateResponse, err := cryptoClient.DigestUpdate(context.Background(), digestUpdateRequest)
if err != nil {
	panic(fmt.Errorf("Digest update error: %s", err))
}
digestUpdateRequest = &pb.DigestUpdateRequest{
	State: digestUpdateResponse.State,
	Data:  digestData[64:],
}
digestUpdateResponse, err = cryptoClient.DigestUpdate(context.Background(), digestUpdateRequest)
if err != nil {
	panic(fmt.Errorf("Digest update error: %s", err))
}
digestFinalRequestInfo := &pb.DigestFinalRequest{
	State: digestUpdateResponse.State,
}
digestFinalResponse, err := cryptoClient.DigestFinal(context.Background(), digestFinalRequestInfo)
if err != nil {
	panic(fmt.Errorf("Digest final error: %s", err))
} else {
	fmt.Printf("Digest data using multiple operations: %x\n", digestFinalResponse.Digest)
}
Output:

Digest data using a single digest operation: ad4e0b6e309d192862ec6db692d17072ddd3a98ccd37afe642a04f7ca554c94c
Digest data using multiple operations: ad4e0b6e309d192862ec6db692d17072ddd3a98ccd37afe642a04f7ca554c94c
Example (EncryptAndDecrypt)

Example_encryptAndDecrypt encrypts and decrypts plain text Flow: connect, generate AES key, generate IV, encrypt multi-part data, decrypt multi-part data

conn, err := grpc.Dial(address, callOpts...)
if err != nil {
	panic(fmt.Errorf("Could not connect to server: %s", err))
}
defer conn.Close()

cryptoClient := pb.NewCryptoClient(conn)
keyLen := 128
keyTemplate := ep11.EP11Attributes{
	ep11.CKA_VALUE_LEN:   keyLen / 8,
	ep11.CKA_WRAP:        false,
	ep11.CKA_UNWRAP:      false,
	ep11.CKA_ENCRYPT:     true,
	ep11.CKA_DECRYPT:     true,
	ep11.CKA_EXTRACTABLE: false, // set to false!
	ep11.CKA_TOKEN:       true,  // ignored by EP11
}

keyGenMsg := &pb.GenerateKeyRequest{
	Mech:     &pb.Mechanism{Mechanism: ep11.CKM_AES_KEY_GEN},
	Template: util.AttributeMap(keyTemplate),
}

generateKeyStatus, err := cryptoClient.GenerateKey(context.Background(), keyGenMsg)
if err != nil {
	panic(fmt.Errorf("GenerateKey Error: %s", err))
}
fmt.Println("Generated AES Key")

rngTemplate := &pb.GenerateRandomRequest{
	Len: (uint64)(ep11.AES_BLOCK_SIZE),
}
rng, err := cryptoClient.GenerateRandom(context.Background(), rngTemplate)
if err != nil {
	panic(fmt.Errorf("GenerateRandom Error: %s", err))
}
iv := rng.Rnd[:ep11.AES_BLOCK_SIZE]
fmt.Println("Generated IV")

encipherInitInfo := &pb.EncryptInitRequest{
	Mech: &pb.Mechanism{Mechanism: ep11.CKM_AES_CBC_PAD, Parameter: &pb.Mechanism_ParameterB{ParameterB: iv}},
	Key:  generateKeyStatus.KeyBytes, // you may want to store this
}
cipherStateInit, err := cryptoClient.EncryptInit(context.Background(), encipherInitInfo)
if err != nil {
	panic(fmt.Errorf("Failed EncryptInit [%s]", err))
}

plain := []byte("Hello, this is a very long and creative message without any imagination")

encipherDataUpdate := &pb.EncryptUpdateRequest{
	State: cipherStateInit.State,
	Plain: plain[:20],
}
encipherStateUpdate, err := cryptoClient.EncryptUpdate(context.Background(), encipherDataUpdate)
if err != nil {
	panic(fmt.Errorf("Failed Encrypt [%s]", err))
}

ciphertext := encipherStateUpdate.Ciphered[:]
encipherDataUpdate = &pb.EncryptUpdateRequest{
	State: encipherStateUpdate.State,
	Plain: plain[20:],
}
encipherStateUpdate, err = cryptoClient.EncryptUpdate(context.Background(), encipherDataUpdate)
if err != nil {
	panic(fmt.Errorf("Failed Encrypt [%s]", err))
}

ciphertext = append(ciphertext, encipherStateUpdate.Ciphered...)
encipherDataFinal := &pb.EncryptFinalRequest{
	State: encipherStateUpdate.State,
}
encipherStateFinal, err := cryptoClient.EncryptFinal(context.Background(), encipherDataFinal)
if err != nil {
	panic(fmt.Errorf("Failed EncryptFinal [%s]", err))
}

ciphertext = append(ciphertext, encipherStateFinal.Ciphered...)
fmt.Println("Encrypted message")

decipherInitInfo := &pb.DecryptInitRequest{
	Mech: &pb.Mechanism{Mechanism: ep11.CKM_AES_CBC_PAD, Parameter: &pb.Mechanism_ParameterB{ParameterB: iv}},
	Key:  generateKeyStatus.KeyBytes, // you may want to store this
}
decipherStateInit, err := cryptoClient.DecryptInit(context.Background(), decipherInitInfo)
if err != nil {
	panic(fmt.Errorf("Failed DecryptInit [%s]", err))
}

decipherDataUpdate := &pb.DecryptUpdateRequest{
	State:    decipherStateInit.State,
	Ciphered: ciphertext[:16],
}
decipherStateUpdate, err := cryptoClient.DecryptUpdate(context.Background(), decipherDataUpdate)
if err != nil {
	panic(fmt.Errorf("Failed DecryptUpdate [%s]", err))
}

plaintext := decipherStateUpdate.Plain[:]
decipherDataUpdate = &pb.DecryptUpdateRequest{
	State:    decipherStateUpdate.State,
	Ciphered: ciphertext[16:],
}
decipherStateUpdate, err = cryptoClient.DecryptUpdate(context.Background(), decipherDataUpdate)
if err != nil {
	panic(fmt.Errorf("Failed DecryptUpdate [%s]", err))
}
plaintext = append(plaintext, decipherStateUpdate.Plain...)

decipherDataFinal := &pb.DecryptFinalRequest{
	State: decipherStateUpdate.State,
}
decipherStateFinal, err := cryptoClient.DecryptFinal(context.Background(), decipherDataFinal)
if err != nil {
	panic(fmt.Errorf("Failed DecryptFinal [%s]", err))
}
plaintext = append(plaintext, decipherStateFinal.Plain...)

if !reflect.DeepEqual(plain, plaintext) {
	panic(fmt.Errorf("Failed comparing plain text of cipher single"))
}

fmt.Printf("Decrypted message\n%s\n", plaintext)
Output:

Generated AES Key
Generated IV
Encrypted message
Decrypted message
Hello, this is a very long and creative message without any imagination
Example (GetMechanismInfo)

Example_getMechanismInfo retrieves a mechanism list and retrieves detailed information for the CKM_RSA_PKCS mechanism Flow: connect, get mechanism list, get mechanism info

conn, err := grpc.Dial(address, callOpts...)
if err != nil {
	panic(fmt.Errorf("Could not connect to server: %s", err))
}
defer conn.Close()

cryptoClient := pb.NewCryptoClient(conn)

mechanismListRequest := &pb.GetMechanismListRequest{}
mechanismListResponse, err := cryptoClient.GetMechanismList(context.Background(), mechanismListRequest)
if err != nil {
	panic(fmt.Errorf("Get mechanism list error: %s", err))
}
fmt.Printf("Got mechanism list:\n%v ...\n", mechanismListResponse.Mechs[:1])

mechanismInfoRequest := &pb.GetMechanismInfoRequest{
	Mech: ep11.CKM_RSA_PKCS,
}
_, err = cryptoClient.GetMechanismInfo(context.Background(), mechanismInfoRequest)
if err != nil {
	panic(fmt.Errorf("Get mechanism info error: %s", err))
}
Output:

Got mechanism list:
[CKM_RSA_PKCS] ...
Example (SignAndVerifyToTestErrorHandling)

Example_signAndVerifyToTestErrorHandling signs some data, modifies the signature and verifies the expected returned error code Flow: connect, generate ECDSA key pair, sign single-part data, modify signature to force verify error,

verify single-part data, ensure proper error is returned
conn, err := grpc.Dial(address, callOpts...)
if err != nil {
	panic(fmt.Errorf("Could not connect to server: %s", err))
}
defer conn.Close()

cryptoClient := pb.NewCryptoClient(conn)

ecParameters, err := asn1.Marshal(util.OIDNamedCurveP256)
if err != nil {
	panic(fmt.Errorf("Unable to encode parameter OID: %s", err))
}

publicKeyECTemplate := ep11.EP11Attributes{
	ep11.CKA_EC_PARAMS:   ecParameters,
	ep11.CKA_VERIFY:      true,
	ep11.CKA_EXTRACTABLE: false,
}
privateKeyECTemplate := ep11.EP11Attributes{
	ep11.CKA_SIGN:        true,
	ep11.CKA_EXTRACTABLE: false,
}
generateECKeypairRequest := &pb.GenerateKeyPairRequest{
	Mech:            &pb.Mechanism{Mechanism: ep11.CKM_EC_KEY_PAIR_GEN},
	PubKeyTemplate:  util.AttributeMap(publicKeyECTemplate),
	PrivKeyTemplate: util.AttributeMap(privateKeyECTemplate),
}
generateKeyPairStatus, err := cryptoClient.GenerateKeyPair(context.Background(), generateECKeypairRequest)
if err != nil {
	panic(fmt.Errorf("GenerateKeyPair error: %s", err))
}

fmt.Println("Generated ECDSA PKCS key pair")

// Sign data
signInitRequest := &pb.SignInitRequest{
	Mech:    &pb.Mechanism{Mechanism: ep11.CKM_ECDSA},
	PrivKey: generateKeyPairStatus.PrivKeyBytes,
}
signInitResponse, err := cryptoClient.SignInit(context.Background(), signInitRequest)
if err != nil {
	panic(fmt.Errorf("SignInit error: %s", err))
}
signData := sha256.Sum256([]byte("This data needs to be signed"))
signRequest := &pb.SignRequest{
	State: signInitResponse.State,
	Data:  signData[:],
}
SignResponse, err := cryptoClient.Sign(context.Background(), signRequest)
if err != nil {
	panic(fmt.Errorf("Sign error: %s", err))
}
fmt.Println("Data signed")

// Modify signature to force returned error code
SignResponse.Signature[0] = 255

verifyInitRequest := &pb.VerifyInitRequest{
	Mech:   &pb.Mechanism{Mechanism: ep11.CKM_ECDSA},
	PubKey: generateKeyPairStatus.PubKeyBytes,
}
verifyInitResponse, err := cryptoClient.VerifyInit(context.Background(), verifyInitRequest)
if err != nil {
	panic(fmt.Errorf("VerifyInit error: %s", err))
}
verifyRequest := &pb.VerifyRequest{
	State:     verifyInitResponse.State,
	Data:      []byte(signData[:]),
	Signature: SignResponse.Signature,
}
_, err = cryptoClient.Verify(context.Background(), verifyRequest)

if ok, ep11Status := util.Convert(err); !ok {
	if ep11Status.Code == ep11.CKR_SIGNATURE_INVALID {
		fmt.Printf("Invalid signature\n")
		return
	}
	panic(fmt.Errorf("Verify error: [%d]: %s", ep11Status.Code, ep11Status.Detail))
}
Output:

Generated ECDSA PKCS key pair
Data signed
Invalid signature
Example (SignAndVerifyUsingECDSAKeyPair)

Example_signAndVerifyUsingECDSAKeyPair generates an ECDSA key pair and uses the key pair to sign and verify data Flow: connect, generate ECDSA key pair, sign single-part data, verify single-part data

conn, err := grpc.Dial(address, callOpts...)
if err != nil {
	panic(fmt.Errorf("Could not connect to server: %s", err))
}
defer conn.Close()

cryptoClient := pb.NewCryptoClient(conn)

ecParameters, err := asn1.Marshal(util.OIDNamedCurveP256)
if err != nil {
	panic(fmt.Errorf("Unable to encode parameter OID: %s", err))
}

publicKeyECTemplate := ep11.EP11Attributes{
	ep11.CKA_EC_PARAMS:   ecParameters,
	ep11.CKA_VERIFY:      true,
	ep11.CKA_EXTRACTABLE: false,
}
privateKeyECTemplate := ep11.EP11Attributes{
	ep11.CKA_SIGN:        true,
	ep11.CKA_EXTRACTABLE: false,
}
generateECKeypairRequest := &pb.GenerateKeyPairRequest{
	Mech:            &pb.Mechanism{Mechanism: ep11.CKM_EC_KEY_PAIR_GEN},
	PubKeyTemplate:  util.AttributeMap(publicKeyECTemplate),
	PrivKeyTemplate: util.AttributeMap(privateKeyECTemplate),
}
generateKeyPairStatus, err := cryptoClient.GenerateKeyPair(context.Background(), generateECKeypairRequest)
if err != nil {
	panic(fmt.Errorf("GenerateKeyPair error: %s", err))
}

fmt.Println("Generated ECDSA PKCS key pair")

// Sign data
signInitRequest := &pb.SignInitRequest{
	Mech:    &pb.Mechanism{Mechanism: ep11.CKM_ECDSA},
	PrivKey: generateKeyPairStatus.PrivKeyBytes,
}
signInitResponse, err := cryptoClient.SignInit(context.Background(), signInitRequest)
if err != nil {
	panic(fmt.Errorf("SignInit error: %s", err))
}
signData := sha256.Sum256([]byte("This data needs to be signed"))
signRequest := &pb.SignRequest{
	State: signInitResponse.State,
	Data:  signData[:],
}
SignResponse, err := cryptoClient.Sign(context.Background(), signRequest)
if err != nil {
	panic(fmt.Errorf("Sign error: %s", err))
}
fmt.Println("Data signed")

verifyInitRequest := &pb.VerifyInitRequest{
	Mech:   &pb.Mechanism{Mechanism: ep11.CKM_ECDSA},
	PubKey: generateKeyPairStatus.PubKeyBytes,
}
verifyInitResponse, err := cryptoClient.VerifyInit(context.Background(), verifyInitRequest)
if err != nil {
	panic(fmt.Errorf("VerifyInit error: %s", err))
}
verifyRequest := &pb.VerifyRequest{
	State:     verifyInitResponse.State,
	Data:      []byte(signData[:]),
	Signature: SignResponse.Signature,
}
_, err = cryptoClient.Verify(context.Background(), verifyRequest)
if ok, ep11Status := util.Convert(err); !ok {
	if ep11Status.Code == ep11.CKR_SIGNATURE_INVALID {
		panic(fmt.Errorf("Invalid signature"))
	} else {
		panic(fmt.Errorf("Verify error: [%d]: %s", ep11Status.Code, ep11Status.Detail))
	}
}
fmt.Println("Verified")
Output:

Generated ECDSA PKCS key pair
Data signed
Verified
Example (SignAndVerifyUsingECDSAKeyPairWithSchnorr)
conn, err := grpc.Dial(address, callOpts...)
if err != nil {
	panic(fmt.Errorf("Could not connect to server: %s", err))
}
defer conn.Close()

cryptoClient := pb.NewCryptoClient(conn)

ecParameters, err := asn1.Marshal(util.OIDNamedCurveSecp256k1)
if err != nil {
	panic(fmt.Errorf("Unable to encode parameter OID: %s", err))
}

publicKeyECTemplate := ep11.EP11Attributes{
	ep11.CKA_EC_PARAMS:   ecParameters,
	ep11.CKA_VERIFY:      true,
	ep11.CKA_EXTRACTABLE: false,
}
privateKeyECTemplate := ep11.EP11Attributes{
	ep11.CKA_SIGN:        true,
	ep11.CKA_EXTRACTABLE: false,
}
generateECKeypairRequest := &pb.GenerateKeyPairRequest{
	Mech:            &pb.Mechanism{Mechanism: ep11.CKM_EC_KEY_PAIR_GEN},
	PubKeyTemplate:  util.AttributeMap(publicKeyECTemplate),
	PrivKeyTemplate: util.AttributeMap(privateKeyECTemplate),
}
generateKeyPairStatus, err := cryptoClient.GenerateKeyPair(context.Background(), generateECKeypairRequest)
if err != nil {
	panic(fmt.Errorf("GenerateKeyPair error: %s", err))
}

fmt.Println("Generated ECDSA PKCS key pair")

// Sign data
signData := sha256.Sum256([]byte("This data needs to be signed"))
signSingleRequest := &pb.SignSingleRequest{
	Mech: &pb.Mechanism{
		Mechanism: ep11.CKM_IBM_ECDSA_OTHER,
		Parameter: &pb.Mechanism_ECSGParameter{
			ECSGParameter: &pb.ECSGParm{
				Type: pb.ECSGParm_CkEcsgIbmEcsdsaS256,
			},
		},
	},
	PrivKey: generateKeyPairStatus.PrivKeyBytes,
	Data:    signData[:],
}
signSingleResponse, err := cryptoClient.SignSingle(context.Background(), signSingleRequest)
if err != nil {
	panic(fmt.Errorf("SignSingle error: %s", err))
} else {
	fmt.Println("Data signed")
}

verifySingleRequest := &pb.VerifySingleRequest{
	Mech: &pb.Mechanism{
		Mechanism: ep11.CKM_IBM_ECDSA_OTHER,
		Parameter: &pb.Mechanism_ECSGParameter{
			ECSGParameter: &pb.ECSGParm{
				Type: pb.ECSGParm_CkEcsgIbmEcsdsaS256,
			},
		},
	},
	PubKey:    generateKeyPairStatus.PubKeyBytes,
	Data:      signData[:],
	Signature: signSingleResponse.Signature,
}
_, err = cryptoClient.VerifySingle(context.Background(), verifySingleRequest)
if ok, ep11Status := util.Convert(err); !ok {
	if ep11Status.Code == ep11.CKR_SIGNATURE_INVALID {
		panic(fmt.Errorf("Invalid signature"))
	} else {
		panic(fmt.Errorf("Verify error: [%d]: %s", ep11Status.Code, ep11Status.Detail))
	}
}
fmt.Println("Verified")
Output:

Generated ECDSA PKCS key pair
Data signed
Verified
Example (SignAndVerifyUsingRSAKeyPair)

Example_signAndVerifyUsingRSAKeyPair signs some data and verifies it Flow: connect, generate RSA key pair, sign single-part data, verify single-part data

conn, err := grpc.Dial(address, callOpts...)
if err != nil {
	panic(fmt.Errorf("did not connect: %v", err))
}
defer conn.Close()

cryptoClient := pb.NewCryptoClient(conn)

// Generate RSA key pairs
publicExponent := []byte{0x11}
publicKeyTemplate := ep11.EP11Attributes{
	ep11.CKA_ENCRYPT:         true,
	ep11.CKA_VERIFY:          true, // to verify a signature
	ep11.CKA_MODULUS_BITS:    2048,
	ep11.CKA_PUBLIC_EXPONENT: publicExponent,
	ep11.CKA_EXTRACTABLE:     false,
}
privateKeyTemplate := ep11.EP11Attributes{
	ep11.CKA_PRIVATE:     true,
	ep11.CKA_SENSITIVE:   true,
	ep11.CKA_DECRYPT:     true,
	ep11.CKA_SIGN:        true, // to generate a signature
	ep11.CKA_EXTRACTABLE: false,
}
generateKeypairRequest := &pb.GenerateKeyPairRequest{
	Mech:            &pb.Mechanism{Mechanism: ep11.CKM_RSA_PKCS_KEY_PAIR_GEN},
	PubKeyTemplate:  util.AttributeMap(publicKeyTemplate),
	PrivKeyTemplate: util.AttributeMap(privateKeyTemplate),
}
generateKeyPairStatus, err := cryptoClient.GenerateKeyPair(context.Background(), generateKeypairRequest)
if err != nil {
	panic(fmt.Errorf("GenerateKeyPair error: %s", err))
}
fmt.Println("Generated RSA PKCS key pair")

// Sign data
signInitRequest := &pb.SignInitRequest{
	Mech:    &pb.Mechanism{Mechanism: ep11.CKM_SHA1_RSA_PKCS},
	PrivKey: generateKeyPairStatus.PrivKeyBytes,
}
signInitResponse, err := cryptoClient.SignInit(context.Background(), signInitRequest)
if err != nil {
	panic(fmt.Errorf("SignInit error: %s", err))
}

signData := sha256.Sum256([]byte("This data needs to be signed"))
signRequest := &pb.SignRequest{
	State: signInitResponse.State,
	Data:  []byte(signData[:]),
}
SignResponse, err := cryptoClient.Sign(context.Background(), signRequest)
if err != nil {
	panic(fmt.Errorf("Sign error: %s", err))
}
fmt.Println("Data signed")

verifyInitRequest := &pb.VerifyInitRequest{
	Mech:   &pb.Mechanism{Mechanism: ep11.CKM_SHA1_RSA_PKCS},
	PubKey: generateKeyPairStatus.PubKeyBytes,
}
verifyInitResponse, err := cryptoClient.VerifyInit(context.Background(), verifyInitRequest)
if err != nil {
	panic(fmt.Errorf("VerifyInit error: %s", err))
}
verifyRequest := &pb.VerifyRequest{
	State:     verifyInitResponse.State,
	Data:      []byte(signData[:]),
	Signature: SignResponse.Signature,
}
_, err = cryptoClient.Verify(context.Background(), verifyRequest)
if ok, ep11Status := util.Convert(err); !ok {
	if ep11Status.Code == ep11.CKR_SIGNATURE_INVALID {
		panic(fmt.Errorf("Invalid signature"))
	} else {
		panic(fmt.Errorf("Verify error: [%d]: %s", ep11Status.Code, ep11Status.Detail))
	}
}
fmt.Println("Verified")
Output:

Generated RSA PKCS key pair
Data signed
Verified
Example (Slip10DeriveKey)
conn, err := grpc.Dial(address, callOpts...)
if err != nil {
	panic(fmt.Errorf("Could not connect to server: %s", err))
}
defer conn.Close()
cryptoClient := pb.NewCryptoClient(conn)

// SLIP10 has been verified for NIST P-256 and Secp256k1
supportedCurves := []asn1.ObjectIdentifier{util.OIDNamedCurveP256, util.OIDNamedCurveSecp256k1, util.OIDNamedCurveED25519}
for _, oid := range supportedCurves {
	fmt.Printf("Curve: %+v\n", oid)
	slip10_testCurve(cryptoClient, oid)
}
Output:

Curve: 1.2.840.10045.3.1.7
Generated Generic Secret Key
Derived Key type=CkSLIP0010MASTERK index=0
Derived Key type=CkSLIP0010PRV2PRV index=2147483648
Derived Key type=CkSLIP0010PRV2PUB index=2147483648
Derived Key type=CkSLIP0010PRV2PRV index=2147483649
Derived Key type=CkSLIP0010PRV2PUB index=2147483649
Derived Key type=CkSLIP0010PRV2PRV index=2147483650
Derived Key type=CkSLIP0010PRV2PUB index=2147483650
Derived Key type=CkSLIP0010PRV2PRV index=2147483648
Derived Key type=CkSLIP0010PRV2PUB index=2147483648
Derived Key type=CkSLIP0010PRV2PRV index=2147483649
Derived Key type=CkSLIP0010PRV2PUB index=2147483649
Derived Key type=CkSLIP0010PRV2PRV index=2147483650
Derived Key type=CkSLIP0010PRV2PUB index=2147483650
Derived Key type=CkSLIP0010PRV2PRV index=2147483648
Derived Key type=CkSLIP0010PRV2PUB index=2147483648
Derived Key type=CkSLIP0010PRV2PRV index=2147483649
Derived Key type=CkSLIP0010PRV2PUB index=2147483649
Derived Key type=CkSLIP0010PRV2PRV index=2147483650
Derived Key type=CkSLIP0010PRV2PUB index=2147483650
Data signed
Signature verified
Data signed
Signature verified
Data signed
Signature verified
Data signed
Signature verified
Data signed
Signature verified
Data signed
Signature verified
Data signed
Signature verified
Data signed
Signature verified
Data signed
Signature verified
Curve: 1.3.132.0.10
Generated Generic Secret Key
Derived Key type=CkSLIP0010MASTERK index=0
Derived Key type=CkSLIP0010PRV2PRV index=2147483648
Derived Key type=CkSLIP0010PRV2PUB index=2147483648
Derived Key type=CkSLIP0010PRV2PRV index=2147483649
Derived Key type=CkSLIP0010PRV2PUB index=2147483649
Derived Key type=CkSLIP0010PRV2PRV index=2147483650
Derived Key type=CkSLIP0010PRV2PUB index=2147483650
Derived Key type=CkSLIP0010PRV2PRV index=2147483648
Derived Key type=CkSLIP0010PRV2PUB index=2147483648
Derived Key type=CkSLIP0010PRV2PRV index=2147483649
Derived Key type=CkSLIP0010PRV2PUB index=2147483649
Derived Key type=CkSLIP0010PRV2PRV index=2147483650
Derived Key type=CkSLIP0010PRV2PUB index=2147483650
Derived Key type=CkSLIP0010PRV2PRV index=2147483648
Derived Key type=CkSLIP0010PRV2PUB index=2147483648
Derived Key type=CkSLIP0010PRV2PRV index=2147483649
Derived Key type=CkSLIP0010PRV2PUB index=2147483649
Derived Key type=CkSLIP0010PRV2PRV index=2147483650
Derived Key type=CkSLIP0010PRV2PUB index=2147483650
Data signed
Signature verified
Data signed
Signature verified
Data signed
Signature verified
Data signed
Signature verified
Data signed
Signature verified
Data signed
Signature verified
Data signed
Signature verified
Data signed
Signature verified
Data signed
Signature verified
Curve: 1.3.101.112
Generated Generic Secret Key
Derived Key type=CkSLIP0010MASTERK index=0
Derived Key type=CkSLIP0010PRV2PRV index=2147483648
Derived Key type=CkSLIP0010PRV2PUB index=2147483648
Derived Key type=CkSLIP0010PRV2PRV index=2147483649
Derived Key type=CkSLIP0010PRV2PUB index=2147483649
Derived Key type=CkSLIP0010PRV2PRV index=2147483650
Derived Key type=CkSLIP0010PRV2PUB index=2147483650
Derived Key type=CkSLIP0010PRV2PRV index=2147483648
Derived Key type=CkSLIP0010PRV2PUB index=2147483648
Derived Key type=CkSLIP0010PRV2PRV index=2147483649
Derived Key type=CkSLIP0010PRV2PUB index=2147483649
Derived Key type=CkSLIP0010PRV2PRV index=2147483650
Derived Key type=CkSLIP0010PRV2PUB index=2147483650
Derived Key type=CkSLIP0010PRV2PRV index=2147483648
Derived Key type=CkSLIP0010PRV2PUB index=2147483648
Derived Key type=CkSLIP0010PRV2PRV index=2147483649
Derived Key type=CkSLIP0010PRV2PUB index=2147483649
Derived Key type=CkSLIP0010PRV2PRV index=2147483650
Derived Key type=CkSLIP0010PRV2PUB index=2147483650
Data signed
Signature verified
Data signed
Signature verified
Data signed
Signature verified
Data signed
Signature verified
Data signed
Signature verified
Data signed
Signature verified
Data signed
Signature verified
Data signed
Signature verified
Data signed
Signature verified
Example (Slip10_cross_signAndVerify)
conn, err := grpc.Dial(address, callOpts...)
if err != nil {
	panic(fmt.Errorf("Could not connect to server: %s", err))
}
defer conn.Close()
cryptoClient := pb.NewCryptoClient(conn)

// SLIP10 has been verified for NIST P-256 and Secp256k1
//util.OIDNamedCurveP256, util.OIDNamedCurveSecp256k1, util.OIDNamedCurveED25519

//generate random seed key
generateKeyRequest := &pb.GenerateKeyRequest{
	Mech: &pb.Mechanism{Mechanism: ep11.CKM_GENERIC_SECRET_KEY_GEN},
	Template: util.AttributeMap(
		ep11.EP11Attributes{
			ep11.CKA_KEY_TYPE:        ep11.CKK_GENERIC_SECRET,
			ep11.CKA_CLASS:           ep11.CKO_SECRET_KEY,
			ep11.CKA_VALUE_LEN:       (uint64)(256 / 8),
			ep11.CKA_WRAP:            false,
			ep11.CKA_UNWRAP:          false,
			ep11.CKA_SIGN:            true,
			ep11.CKA_VERIFY:          true,
			ep11.CKA_EXTRACTABLE:     false,
			ep11.CKA_DERIVE:          true,
			ep11.CKA_IBM_USE_AS_DATA: true,
		},
	),
}
generateKeyResponse, err := cryptoClient.GenerateKey(context.Background(), generateKeyRequest)
if err != nil {
	panic(fmt.Errorf("Generated Generic Secret Key error: %+v %s", generateKeyRequest, err))
} else {
	fmt.Println("Generated Generic Secret Key")
}

const hardened = 0x80000000

//keys of NIST P-256
var publicKey_p256, privateKey_p256 []byte
masterSecretKey_p256, masterChainCode_p256 := slip10_deriveKey(
	cryptoClient,
	pb.BTCDeriveParm_CkSLIP0010MASTERK,
	util.OIDNamedCurveP256,
	0,
	generateKeyResponse.KeyBytes,
	nil,
)
privateKey_p256, _ = slip10_deriveKey(
	cryptoClient,
	pb.BTCDeriveParm_CkSLIP0010PRV2PRV,
	util.OIDNamedCurveP256,
	hardened,
	masterSecretKey_p256,
	masterChainCode_p256,
)
publicKey_p256, _ = slip10_deriveKey(
	cryptoClient,
	pb.BTCDeriveParm_CkSLIP0010PRV2PUB,
	util.OIDNamedCurveP256,
	hardened,
	masterSecretKey_p256,
	masterChainCode_p256,
)

//keys of Secp256k1
var privateKey_256k1, publicKey_256k1 []byte
masterSecretKey_256k1, masterChainCode_256k1 := slip10_deriveKey(
	cryptoClient,
	pb.BTCDeriveParm_CkSLIP0010MASTERK,
	util.OIDNamedCurveSecp256k1,
	0,
	generateKeyResponse.KeyBytes,
	nil,
)
privateKey_256k1, _ = slip10_deriveKey(
	cryptoClient,
	pb.BTCDeriveParm_CkSLIP0010PRV2PRV,
	util.OIDNamedCurveSecp256k1,
	hardened,
	masterSecretKey_256k1,
	masterChainCode_256k1,
)
publicKey_256k1, _ = slip10_deriveKey(
	cryptoClient,
	pb.BTCDeriveParm_CkSLIP0010PRV2PUB,
	util.OIDNamedCurveSecp256k1,
	hardened,
	masterSecretKey_256k1,
	masterChainCode_256k1,
)

//keys of ED25519
var privateKey_ed25519, publicKey_ed25519 []byte
masterSecretKey_ed25519, masterChainCode_ed25519 := slip10_deriveKey(
	cryptoClient,
	pb.BTCDeriveParm_CkSLIP0010MASTERK,
	util.OIDNamedCurveED25519,
	0,
	generateKeyResponse.KeyBytes,
	nil,
)
privateKey_ed25519, _ = slip10_deriveKey(
	cryptoClient,
	pb.BTCDeriveParm_CkSLIP0010PRV2PRV,
	util.OIDNamedCurveED25519,
	hardened,
	masterSecretKey_ed25519,
	masterChainCode_ed25519,
)
publicKey_ed25519, _ = slip10_deriveKey(
	cryptoClient,
	pb.BTCDeriveParm_CkSLIP0010PRV2PUB,
	util.OIDNamedCurveED25519,
	hardened,
	masterSecretKey_ed25519,
	masterChainCode_ed25519,
)

//signSingle, and verifyInit/verify
slip10_signSingleAndVerify(cryptoClient, util.OIDNamedCurveP256, privateKey_p256, publicKey_p256)
slip10_signSingleAndVerify(cryptoClient, util.OIDNamedCurveSecp256k1, privateKey_256k1, publicKey_256k1)
slip10_signSingleAndVerify(cryptoClient, util.OIDNamedCurveED25519, privateKey_ed25519, publicKey_ed25519)
//signInit/sign, verifySingle
slip10_signAndVerifyInitAndSingle(cryptoClient, util.OIDNamedCurveP256, privateKey_p256, publicKey_p256)
slip10_signAndVerifyInitAndSingle(cryptoClient, util.OIDNamedCurveSecp256k1, privateKey_256k1, publicKey_256k1)
slip10_signAndVerifyInitAndSingle(cryptoClient, util.OIDNamedCurveED25519, privateKey_ed25519, publicKey_ed25519)
Output:

Generated Generic Secret Key
Derived Key type=CkSLIP0010MASTERK index=0
Derived Key type=CkSLIP0010PRV2PRV index=2147483648
Derived Key type=CkSLIP0010PRV2PUB index=2147483648
Derived Key type=CkSLIP0010MASTERK index=0
Derived Key type=CkSLIP0010PRV2PRV index=2147483648
Derived Key type=CkSLIP0010PRV2PUB index=2147483648
Derived Key type=CkSLIP0010MASTERK index=0
Derived Key type=CkSLIP0010PRV2PRV index=2147483648
Derived Key type=CkSLIP0010PRV2PUB index=2147483648
Data signed - 1.2.840.10045.3.1.7
Signature verified - 1.2.840.10045.3.1.7
Data signed - 1.3.132.0.10
Signature verified - 1.3.132.0.10
Data signed - 1.3.101.112
Signature verified - 1.3.101.112
Data signed - 1.2.840.10045.3.1.7
Signature verified - 1.2.840.10045.3.1.7
Data signed - 1.3.132.0.10
Signature verified - 1.3.132.0.10
Data signed - 1.3.101.112
Signature verified - 1.3.101.112
Example (Slip10_invalid_signAndVerify)
conn, err := grpc.Dial(address, callOpts...)
if err != nil {
	panic(fmt.Errorf("Could not connect to server: %s", err))
}
defer conn.Close()
cryptoClient := pb.NewCryptoClient(conn)

// SLIP10 has been verified for NIST P-256 and Secp256k1
//util.OIDNamedCurveP256, util.OIDNamedCurveSecp256k1, util.OIDNamedCurveED25519

//generate random seed key
generateKeyRequest := &pb.GenerateKeyRequest{
	Mech: &pb.Mechanism{Mechanism: ep11.CKM_GENERIC_SECRET_KEY_GEN},
	Template: util.AttributeMap(
		ep11.EP11Attributes{
			ep11.CKA_KEY_TYPE:        ep11.CKK_GENERIC_SECRET,
			ep11.CKA_CLASS:           ep11.CKO_SECRET_KEY,
			ep11.CKA_VALUE_LEN:       (uint64)(256 / 8),
			ep11.CKA_WRAP:            false,
			ep11.CKA_UNWRAP:          false,
			ep11.CKA_SIGN:            true,
			ep11.CKA_VERIFY:          true,
			ep11.CKA_EXTRACTABLE:     false,
			ep11.CKA_DERIVE:          true,
			ep11.CKA_IBM_USE_AS_DATA: true,
		},
	),
}
generateKeyResponse, err := cryptoClient.GenerateKey(context.Background(), generateKeyRequest)
if err != nil {
	panic(fmt.Errorf("Generated Generic Secret Key error: %+v %s", generateKeyRequest, err))
} else {
	fmt.Println("Generated Generic Secret Key")
}

const hardened = 0x80000000

//keys of NIST P-256
var publicKey_p256, privateKey_p256 []byte
masterSecretKey_p256, masterChainCode_p256 := slip10_deriveKey(
	cryptoClient,
	pb.BTCDeriveParm_CkSLIP0010MASTERK,
	util.OIDNamedCurveP256,
	0,
	generateKeyResponse.KeyBytes,
	nil,
)
privateKey_p256, _ = slip10_deriveKey(
	cryptoClient,
	pb.BTCDeriveParm_CkSLIP0010PRV2PRV,
	util.OIDNamedCurveP256,
	hardened,
	masterSecretKey_p256,
	masterChainCode_p256,
)
publicKey_p256, _ = slip10_deriveKey(
	cryptoClient,
	pb.BTCDeriveParm_CkSLIP0010PRV2PUB,
	util.OIDNamedCurveP256,
	hardened,
	masterSecretKey_p256,
	masterChainCode_p256,
)

//keys of Secp256k1
var privateKey_256k1, publicKey_256k1 []byte
masterSecretKey_256k1, masterChainCode_256k1 := slip10_deriveKey(
	cryptoClient,
	pb.BTCDeriveParm_CkSLIP0010MASTERK,
	util.OIDNamedCurveSecp256k1,
	0,
	generateKeyResponse.KeyBytes,
	nil,
)
privateKey_256k1, _ = slip10_deriveKey(
	cryptoClient,
	pb.BTCDeriveParm_CkSLIP0010PRV2PRV,
	util.OIDNamedCurveSecp256k1,
	hardened,
	masterSecretKey_256k1,
	masterChainCode_256k1,
)
publicKey_256k1, _ = slip10_deriveKey(
	cryptoClient,
	pb.BTCDeriveParm_CkSLIP0010PRV2PUB,
	util.OIDNamedCurveSecp256k1,
	hardened,
	masterSecretKey_256k1,
	masterChainCode_256k1,
)

//keys of ED25519
var privateKey_ed25519, publicKey_ed25519 []byte
masterSecretKey_ed25519, masterChainCode_ed25519 := slip10_deriveKey(
	cryptoClient,
	pb.BTCDeriveParm_CkSLIP0010MASTERK,
	util.OIDNamedCurveED25519,
	0,
	generateKeyResponse.KeyBytes,
	nil,
)
privateKey_ed25519, _ = slip10_deriveKey(
	cryptoClient,
	pb.BTCDeriveParm_CkSLIP0010PRV2PRV,
	util.OIDNamedCurveED25519,
	hardened,
	masterSecretKey_ed25519,
	masterChainCode_ed25519,
)
publicKey_ed25519, _ = slip10_deriveKey(
	cryptoClient,
	pb.BTCDeriveParm_CkSLIP0010PRV2PUB,
	util.OIDNamedCurveED25519,
	hardened,
	masterSecretKey_ed25519,
	masterChainCode_ed25519,
)
//invalid sign with incorrect curve - NIST P-256 curve
slip10_signAndVerify_crossErr(cryptoClient, util.OIDNamedCurveED25519, privateKey_p256, publicKey_p256)
//nvalid sign with incorrect curve - secp256k1 curve
slip10_signAndVerify_crossErr(cryptoClient, util.OIDNamedCurveED25519, privateKey_256k1, publicKey_256k1)
//invalid sign with incorrect curve- ED25519 curve
slip10_signAndVerify_crossErr(cryptoClient, util.OIDNamedCurveP256, privateKey_ed25519, publicKey_ed25519)
//invalid verification
slip10_signAndVerify_crossErr(cryptoClient, util.OIDNamedCurveP256, privateKey_p256, publicKey_256k1)
slip10_signAndVerify_crossErr(cryptoClient, util.OIDNamedCurveSecp256k1, privateKey_256k1, publicKey_p256)
slip10_signAndVerify_crossErr(cryptoClient, util.OIDNamedCurveED25519, privateKey_ed25519, publicKey_p256)
Output:

Generated Generic Secret Key
Derived Key type=CkSLIP0010MASTERK index=0
Derived Key type=CkSLIP0010PRV2PRV index=2147483648
Derived Key type=CkSLIP0010PRV2PUB index=2147483648
Derived Key type=CkSLIP0010MASTERK index=0
Derived Key type=CkSLIP0010PRV2PRV index=2147483648
Derived Key type=CkSLIP0010PRV2PUB index=2147483648
Derived Key type=CkSLIP0010MASTERK index=0
Derived Key type=CkSLIP0010PRV2PRV index=2147483648
Derived Key type=CkSLIP0010PRV2PUB index=2147483648
SignInit error with invalid Mechanism - 1.3.101.112
SignInit error with invalid Mechanism - 1.3.101.112
SignInit error with invalid Mechanism - 1.2.840.10045.3.1.7
Data signed
Invalid signature
Data signed
Invalid signature
Data signed
VerifyInit error with invalid Mechanism - 1.3.101.112
Example (Tls)

Example_tls tests TLS communication between a client and server using a certificate and private key that are dynamically generated

package main

import (
	"context"
	"crypto/rand"
	"crypto/tls"
	"crypto/x509"
	"crypto/x509/pkix"
	"encoding/asn1"
	"fmt"
	"io/ioutil"
	"math/big"
	"net/http"
	"strings"
	"time"

	"github.com/hodlbirb/hpcs-bip32/golang/ep11"
	pb "github.com/hodlbirb/hpcs-bip32/golang/grpc"
	"github.com/hodlbirb/hpcs-bip32/golang/util"
	grpc "google.golang.org/grpc"
)

// generateECDSAKeyPair generates a 256 bit ECDSA key pair
func generateECDSAKeyPair(cryptoClient pb.CryptoClient) ([]byte, []byte, error) {
	ecParameters, err := asn1.Marshal(util.OIDNamedCurveP256)
	if err != nil {
		return nil, nil, fmt.Errorf("Unable to encode parameter OID: %s", err)
	}
	publicKeyECTemplate := util.NewAttributeMap(
		util.NewAttribute(ep11.CKA_EC_PARAMS, ecParameters),
		util.NewAttribute(ep11.CKA_VERIFY, true),
		util.NewAttribute(ep11.CKA_EXTRACTABLE, false),
	)
	privateKeyECTemplate := util.NewAttributeMap(
		util.NewAttribute(ep11.CKA_SIGN, true),
		util.NewAttribute(ep11.CKA_EXTRACTABLE, false),
	)
	generateECKeypairRequest := &pb.GenerateKeyPairRequest{
		Mech:            &pb.Mechanism{Mechanism: ep11.CKM_EC_KEY_PAIR_GEN},
		PubKeyTemplate:  publicKeyECTemplate,
		PrivKeyTemplate: privateKeyECTemplate,
	}
	var ecKeypairResponse *pb.GenerateKeyPairResponse
	ecKeypairResponse, err = cryptoClient.GenerateKeyPair(context.Background(), generateECKeypairRequest)
	if err != nil {
		return nil, nil, fmt.Errorf("Generate ECDSA key pair error: %s", err)
	}
	return ecKeypairResponse.PrivKey, ecKeypairResponse.PubKey, nil
}

func createECDSASelfSignedCert(privKey *util.EP11PrivateKey, commonName string, sigAlg x509.SignatureAlgorithm) ([]byte, error) {
	template := x509.Certificate{
		SerialNumber: big.NewInt(123456789),
		Subject: pkix.Name{
			CommonName: commonName,
		},
		NotBefore: time.Now(),
		NotAfter:  time.Now().Add(time.Hour * 24 * 180),
	}

	certDERBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, privKey.Public(), privKey)
	if err != nil {
		return nil, fmt.Errorf("Failed to create certificate: %s", err)
	}
	return certDERBytes, nil
}

// StartServer starts https server
func CreateServer(listenAddr string) *http.Server {
	mux := http.NewServeMux()
	mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
		w.Write([]byte("Hello"))
	})
	httpServer := &http.Server{
		Addr:    listenAddr,
		Handler: mux,
	}
	return httpServer
}

func newHTTPTestClient(caCertDER []byte) *http.Client {
	x509Cert, err := x509.ParseCertificate(caCertDER)
	if err != nil {
		fmt.Printf("x509.ParseCertificate failed: %s\n", err)
		return nil
	}
	clientCertPool := x509.NewCertPool()
	// Append the client certificates from the CA
	clientCertPool.AddCert(x509Cert)

	httpClient := &http.Client{
		Transport: &http.Transport{
			TLSClientConfig: &tls.Config{
				ServerName: "localhost",
				RootCAs:    clientCertPool,
			},
		},
	}

	return httpClient
}

func ping(client *http.Client, serverAddr string) (string, error) {
	// serverAddr in format of a.b.c.d:port in ipv4 or [::]:port in ipv6
	var serverPort string
	id := strings.LastIndex(serverAddr, ":")
	if id != -1 {
		serverPort = serverAddr[id:]
	} else {
		serverPort = serverAddr
	}
	fullAddr := "https://localhost" + serverPort

	resp, err := client.Get(fullAddr)
	if err != nil {
		return "", fmt.Errorf("Http client get failed: %s", err)
	}
	data, err := ioutil.ReadAll(resp.Body)
	resp.Body.Close()
	if err != nil {
		return "", fmt.Errorf("ioutil.ReadAll failed: %s", err)
	}
	return string(data), nil
}

// Example_tls tests TLS communication between a client and server using a certificate and private key that are dynamically generated
func main() {
	conn, err := grpc.Dial(address, callOpts...)
	if err != nil {
		fmt.Printf("Could not connect to server: %s", err)
		return
	}
	defer conn.Close()
	cryptoClient := pb.NewCryptoClient(conn)
	privKeyBlob, spki, err := generateECDSAKeyPair(cryptoClient)
	if err != nil {
		fmt.Printf("Failed to generate ECDSA key pair: %s", err)
		return
	}

	// Create signer and raw certificate to build up TLS certificate
	priv, err := util.NewEP11Signer(cryptoClient, privKeyBlob, spki)
	if err != nil {
		fmt.Printf("NewEP11Signer error: %s\n", err)
		return
	}
	certDER, err := createECDSASelfSignedCert(priv, "localhost", x509.ECDSAWithSHA256)
	if err != nil {
		fmt.Printf("createECDSASelfSignedCert error: %s\n", err)
		return
	}
	tlsCert := tls.Certificate{
		Certificate: [][]byte{certDER},
		PrivateKey:  priv,
	}

	// Create and start server thread
	tlsCfg := &tls.Config{
		Certificates: []tls.Certificate{tlsCert},
		ClientAuth:   tls.NoClientCert,
	}
	lis, err := tls.Listen("tcp", ":0", tlsCfg)
	if err != nil {
		fmt.Printf("Failed to listen: %s\n", err)
		return
	}
	httpServer := CreateServer(lis.Addr().String())

	defer httpServer.Close()
	go func() {
		httpServer.Serve(lis)
	}()

	// Create TLS client
	client := newHTTPTestClient(certDER)
	strResp, err := ping(client, lis.Addr().String())
	if err != nil {
		fmt.Printf("Ping failed: %s\n", err)
	} else {
		fmt.Printf("Response data from https server: [%s]\n", strResp)
	}

	return

}
Output:

Response data from https server: [Hello]
Example (WrapAndUnwrapKey)

Example_wrapAndUnWrapKey wraps an AES key with a RSA public key and then unwraps it with the private key Flow: connect, generate AES key, generate RSA key pair, wrap/unwrap AES key with RSA key pair

conn, err := grpc.Dial(address, callOpts...)
if err != nil {
	panic(fmt.Errorf("Could not connect to server: %s", err))
}
defer conn.Close()

cryptoClient := pb.NewCryptoClient(conn)

// Generate a AES key
desKeyTemplate := ep11.EP11Attributes{
	ep11.CKA_VALUE_LEN:   128 / 8,
	ep11.CKA_ENCRYPT:     true,
	ep11.CKA_DECRYPT:     true,
	ep11.CKA_EXTRACTABLE: true, // must be true to be wrapped
}
generateKeyRequest := &pb.GenerateKeyRequest{
	Mech:     &pb.Mechanism{Mechanism: ep11.CKM_AES_KEY_GEN},
	Template: util.AttributeMap(desKeyTemplate),
}
generateNewKeyStatus, err := cryptoClient.GenerateKey(context.Background(), generateKeyRequest)
if err != nil {
	panic(fmt.Errorf("Generate AES key error: %s", err))
} else {
	fmt.Println("Generated AES key")
}

// Generate RSA key pairs
publicExponent := []byte{0x11}
publicKeyTemplate := ep11.EP11Attributes{
	ep11.CKA_ENCRYPT:         true,
	ep11.CKA_WRAP:            true, // to wrap a key
	ep11.CKA_MODULUS_BITS:    2048,
	ep11.CKA_PUBLIC_EXPONENT: publicExponent,
	ep11.CKA_EXTRACTABLE:     false,
}
privateKeyTemplate := ep11.EP11Attributes{
	ep11.CKA_PRIVATE:     true,
	ep11.CKA_SENSITIVE:   true,
	ep11.CKA_DECRYPT:     true,
	ep11.CKA_UNWRAP:      true, // to unwrap a key
	ep11.CKA_EXTRACTABLE: false,
}
generateKeypairRequest := &pb.GenerateKeyPairRequest{
	Mech:            &pb.Mechanism{Mechanism: ep11.CKM_RSA_PKCS_KEY_PAIR_GEN},
	PubKeyTemplate:  util.AttributeMap(publicKeyTemplate),
	PrivKeyTemplate: util.AttributeMap(privateKeyTemplate),
}
generateKeyPairStatus, err := cryptoClient.GenerateKeyPair(context.Background(), generateKeypairRequest)
if err != nil {
	panic(fmt.Errorf("GenerateKeyPair error: %s", err))
}
fmt.Println("Generated PKCS key pair")

wrapKeyRequest := &pb.WrapKeyRequest{
	Mech: &pb.Mechanism{Mechanism: ep11.CKM_RSA_PKCS},
	KeK:  generateKeyPairStatus.PubKeyBytes,
	Key:  generateNewKeyStatus.KeyBytes,
}
wrapKeyResponse, err := cryptoClient.WrapKey(context.Background(), wrapKeyRequest)
if err != nil {
	panic(fmt.Errorf("Wrap AES key error: %s", err))
}
fmt.Println("Wrapped AES key")

desUnwrapKeyTemplate := ep11.EP11Attributes{
	ep11.CKA_CLASS:       ep11.CKO_SECRET_KEY,
	ep11.CKA_KEY_TYPE:    ep11.CKK_AES,
	ep11.CKA_VALUE_LEN:   128 / 8,
	ep11.CKA_ENCRYPT:     true,
	ep11.CKA_DECRYPT:     true,
	ep11.CKA_EXTRACTABLE: true, // must be true to be wrapped
}
unwrapRequest := &pb.UnwrapKeyRequest{
	Mech:     &pb.Mechanism{Mechanism: ep11.CKM_RSA_PKCS},
	KeK:      generateKeyPairStatus.PrivKeyBytes,
	Wrapped:  wrapKeyResponse.Wrapped,
	Template: util.AttributeMap(desUnwrapKeyTemplate),
}
unWrappedResponse, err := cryptoClient.UnwrapKey(context.Background(), unwrapRequest)
if err != nil {
	panic(fmt.Errorf("Unwrap AES key error: %s", err))
}
if !bytes.Equal(generateNewKeyStatus.GetCheckSum()[:3], unWrappedResponse.GetCheckSum()[:3]) {
	panic(fmt.Errorf("Unwrap AES key has a different checksum than the original key"))
} else {
	fmt.Println("Unwrapped AES key")
}
Output:

Generated AES key
Generated PKCS key pair
Wrapped AES key
Unwrapped AES key

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL