public void Provision(string encodedHmacKey, string hostName, string deviceId = "")
{
TpmHandle nvHandle = new TpmHandle(AIOTH_PERSISTED_URI_INDEX + logicalDeviceId);
TpmHandle ownerHandle = new TpmHandle(TpmRh.Owner);
TpmHandle hmacKeyHandle = new TpmHandle(AIOTH_PERSISTED_KEY_HANDLE + logicalDeviceId);
TpmHandle srkHandle = new TpmHandle(SRK_HANDLE);
UTF8Encoding utf8 = new UTF8Encoding();
byte[] nvData = utf8.GetBytes(hostName + "/" + deviceId);
byte[] hmacKey = System.Convert.FromBase64String(encodedHmacKey);
// Open the TPM
Tpm2Device tpmDevice = new TbsDevice();
tpmDevice.Connect();
var tpm = new Tpm2(tpmDevice);
// Define the store
tpm.NvDefineSpace(ownerHandle,
new byte[0],
new NvPublic(nvHandle,
TpmAlgId.Sha256,
NvAttr.Authwrite | NvAttr.Authread | NvAttr.NoDa,
new byte[0],
(ushort)nvData.Length));
// Write the store
tpm.NvWrite(nvHandle, nvHandle, nvData, 0);
// Import the HMAC key under the SRK
TpmPublic hmacPub;
CreationData creationData;
byte[] creationhash;
TkCreation ticket;
TpmPrivate hmacPrv = tpm.Create(srkHandle,
new SensitiveCreate(new byte[0],
hmacKey),
new TpmPublic(TpmAlgId.Sha256,
ObjectAttr.UserWithAuth | ObjectAttr.NoDA | ObjectAttr.Sign,
new byte[0],
new KeyedhashParms(new SchemeHmac(TpmAlgId.Sha256)),
new Tpm2bDigestKeyedhash()),
new byte[0],
new PcrSelection[0],
out hmacPub,
out creationData,
out creationhash,
out ticket);
// Load the HMAC key into the TPM
TpmHandle loadedHmacKey = tpm.Load(srkHandle, hmacPrv, hmacPub);
// Persist the key in NV
tpm.EvictControl(ownerHandle, loadedHmacKey, hmacKeyHandle);
// Unload the transient copy from the TPM
tpm.FlushContext(loadedHmacKey);
}