internal static void NVCounter(Tpm2 tpm) { TpmHandle nvHandle = TpmHandle.NV(3001); tpm._AllowErrors().NvUndefineSpace(TpmRh.Owner, nvHandle); tpm.NvDefineSpace(TpmRh.Owner, AuthValue.FromRandom(8), new NvPublic(nvHandle, TpmAlgId.Sha1, NvAttr.Counter | NvAttr.Authread | NvAttr.Authwrite, null, 8)); tpm.NvIncrement(nvHandle, nvHandle); byte[] nvRead = tpm.NvRead(nvHandle, nvHandle, 8, 0); var initVal = Marshaller.FromTpmRepresentation <ulong>(nvRead); tpm.NvIncrement(nvHandle, nvHandle); nvRead = tpm.NvRead(nvHandle, nvHandle, 8, 0); var finalVal = Marshaller.FromTpmRepresentation <ulong>(nvRead); if (finalVal != initVal + 1) { throw new Exception("NV-counter fail"); } Console.WriteLine("Incremented counter from {0} to {1}.", initVal, finalVal); tpm.NvUndefineSpace(TpmRh.Owner, nvHandle); } //NVCounter
/// <summary> /// Demonstrate use of NV counters. /// </summary> /// <param name="tpm">Reference to the TPM object.</param> void NVCounter(Tpm2 tpm) { // // AuthValue encapsulates an authorization value: essentially a byte-array. // OwnerAuth is the owner authorization value of the TPM-under-test. We // assume that it (and other) auths are set to the default (null) value. // If running on a real TPM, which has been provisioned by Windows, this // value will be different. An administrator can retrieve the owner // authorization value from the registry. // TpmHandle nvHandle = TpmHandle.NV(3001); // // Clean up any slot that was left over from an earlier run // tpm._AllowErrors() .NvUndefineSpace(TpmRh.Owner, nvHandle); // // Scenario 2 - A NV-counter // tpm.NvDefineSpace(TpmRh.Owner, AuthValue.FromRandom(8), new NvPublic(nvHandle, TpmAlgId.Sha1, NvAttr.Counter | NvAttr.Authread | NvAttr.Authwrite, null, 8)); // // Must write before we can read // tpm.NvIncrement(nvHandle, nvHandle); // // Read the current value // byte[] nvRead = tpm.NvRead(nvHandle, nvHandle, 8, 0); var initVal = Marshaller.FromTpmRepresentation <ulong>(nvRead); // // Increment // tpm.NvIncrement(nvHandle, nvHandle); // // Read again and see if the answer is what we expect // nvRead = tpm.NvRead(nvHandle, nvHandle, 8, 0); var finalVal = Marshaller.FromTpmRepresentation <ulong>(nvRead); if (finalVal != initVal + 1) { throw new Exception("NV-counter fail"); } this.textBlock.Text += "Incremented counter from " + initVal.ToString() + " to " + finalVal.ToString() + ". "; // // Clean up // tpm.NvUndefineSpace(TpmRh.Owner, nvHandle); }
private string GetHeldData() { TpmHandle nvUriHandle = new TpmHandle(AIOTH_PERSISTED_URI_INDEX + logicalDeviceId); Byte[] nvData; string iotHubUri = ""; try { // Open the TPM Tpm2Device tpmDevice = new TbsDevice(); tpmDevice.Connect(); var tpm = new Tpm2(tpmDevice); // Read the URI from the TPM Byte[] name; NvPublic nvPublic = tpm.NvReadPublic(nvUriHandle, out name); nvData = tpm.NvRead(nvUriHandle, nvUriHandle, nvPublic.dataSize, 0); // Dispose of the TPM tpm.Dispose(); } catch { return(iotHubUri); } // Convert the data to a srting for output iotHubUri = System.Text.Encoding.UTF8.GetString(nvData); return(iotHubUri); }
internal string GetPersistedUri() { TpmHandle nvUriHandle = new TpmHandle(PERSISTED_URI_INDEX + logicalDeviceId); try { string uri; // Open the TPM Tpm2Device tpmDevice = new TbsDevice(); tpmDevice.Connect(); using (var tpm = new Tpm2(tpmDevice)) { // Read the URI from the TPM NvPublic nvPublic = tpm.NvReadPublic(nvUriHandle, out byte[] name); var nvData = tpm.NvRead(nvUriHandle, nvUriHandle, nvPublic.dataSize, 0); // Convert the data to a srting for output uri = Encoding.UTF8.GetString(nvData); } return(uri); } catch { } return(string.Empty); }
internal static void NVReadWrite(Tpm2 tpm) { // // AuthValue encapsulates an authorization value: essentially a byte-array. // OwnerAuth is the owner authorization value of the TPM-under-test. We // assume that it (and other) auths are set to the default (null) value. // If running on a real TPM, which has been provisioned by Windows, this // value will be different. An administrator can retrieve the owner // authorization value from the registry. // var ownerAuth = new AuthValue(); TpmHandle nvHandle = TpmHandle.NV(3001); // // Clean up any slot that was left over from an earlier run // tpm._AllowErrors() .NvUndefineSpace(TpmRh.Owner, nvHandle); // // Scenario 1 - write and read a 32-byte NV-slot // AuthValue nvAuth = AuthValue.FromRandom(8); tpm.NvDefineSpace(TpmRh.Owner, nvAuth, new NvPublic(nvHandle, TpmAlgId.Sha1, NvAttr.Authread | NvAttr.Authwrite, null, 32)); // // Write some data // var nvData = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7 }; tpm.NvWrite(nvHandle, nvHandle, nvData, 0); // // And read it back // byte[] nvRead = tpm.NvRead(nvHandle, nvHandle, (ushort)nvData.Length, 0); // // Is it correct? // bool correct = nvData.SequenceEqual(nvRead); if (!correct) { throw new Exception("NV data was incorrect."); } Console.WriteLine("NV data written and read."); // // And clean up // tpm.NvUndefineSpace(TpmRh.Owner, nvHandle); }
public static byte[] SafeNvRead(Tpm2 tpm, ushort maxNvOpSize, TpmHandle nvHandle, ushort size, ushort nvOffset = 0) { byte[] contents = new byte[size]; for (ushort offset = 0; offset < size; offset += maxNvOpSize, nvOffset += maxNvOpSize) { var chunkSize = size - offset < maxNvOpSize ? size - offset : maxNvOpSize; var chunk = tpm.NvRead(nvHandle, nvHandle, (ushort)chunkSize, nvOffset); Array.Copy(chunk, 0, contents, offset, chunkSize); } return(contents); }
public static List <AsaNvIndex> DumpNV(Tpm2 tpm) { var output = new List <AsaNvIndex>(); if (tpm == null) { return(output); } byte moreData; do { uint maxHandles = ushort.MaxValue; moreData = tpm.GetCapability(Cap.Handles, ((uint)Ht.NvIndex) << 24, maxHandles, out ICapabilitiesUnion cap); HandleArray handles = (HandleArray)cap; foreach (TpmHandle hh in handles.handle) { NvPublic nvPub = tpm.NvReadPublic(hh, out byte[] nvName); var index = new AsaNvIndex() { Index = hh.handle & 0x00FFFFFF, Attributes = nvPub.attributes }; // We can read with just the owner auth if (nvPub.attributes.HasFlag(NvAttr.Ownerread)) { try { index.value = tpm.NvRead(TpmRh.Owner, hh, nvPub.dataSize, 0).ToList(); } catch (TpmException e) { Log.Verbose("Dumping NV {0} failed ({1}:{2})", hh.handle & 0x00FFFFFF, e.GetType(), e.Message); } } // TODO: Attempt with auth values if DA is disabled output.Add(index); } } while (moreData == 1); return(output); }
public void TestTpmCollector() { var PcrAlgorithm = TpmAlgId.Sha256; if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { var process = TpmSim.GetTpmSimulator(); process.Start(); var nvData = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7 }; uint nvIndex = 3001; var tpmc = new TpmCollector(new CollectorOptions() { Verbose = true }, null, TestMode: true); // Prepare to write to NV 3001 TpmHandle nvHandle = TpmHandle.NV(nvIndex); TcpTpmDevice tcpTpmDevice = new TcpTpmDevice("127.0.0.1", 2321, stopTpm: false); tcpTpmDevice.Connect(); using var tpm = new Tpm2(tcpTpmDevice); tcpTpmDevice.PowerCycle(); tpm.Startup(Su.Clear); try { tpm._AllowErrors() .NvUndefineSpace(TpmRh.Owner, nvHandle); tpm.NvDefineSpace(TpmRh.Owner, null, new NvPublic(nvHandle, TpmAlgId.Sha1, NvAttr.NoDa | NvAttr.Ownerread | NvAttr.Ownerwrite, null, 32)); // Write to NV 3001 tpm.NvWrite(TpmRh.Owner, nvHandle, nvData, 0); var nvOut = tpm.NvRead(TpmRh.Owner, nvHandle, (ushort)nvData.Length, 0); Assert.IsTrue(nvOut.SequenceEqual(nvData)); } catch (TpmException e) { Log.Debug(e, "Failed to Write to NV."); Assert.Fail(); } // Verify that all the PCRs are blank to start with var pcrs = TpmCollector.DumpPCRs(tpm, PcrAlgorithm, new PcrSelection[] { new PcrSelection(PcrAlgorithm, new uint[] { 15, 16 }) }); Assert.IsTrue(pcrs.All(x => x.Value.SequenceEqual(new byte[x.Value.Length]))); // Measure to PCR 16 try { tpm.PcrExtend(TpmHandle.Pcr(16), tpm.PcrEvent(TpmHandle.Pcr(16), nvData)); } catch (TpmException e) { Log.Debug(e, "Failed to Write PCR."); } // Verify that we extended the PCR var pcrs2 = TpmCollector.DumpPCRs(tpm, PcrAlgorithm, new PcrSelection[] { new PcrSelection(PcrAlgorithm, new uint[] { 15, 16 }, 24) }); Assert.IsTrue(pcrs2[(PcrAlgorithm, 15)].SequenceEqual(pcrs[(PcrAlgorithm, 15)]));