internal void SetPersistedUri(string uri) { TpmHandle nvHandle = new TpmHandle(PERSISTED_URI_INDEX + logicalDeviceId); TpmHandle ownerHandle = new TpmHandle(TpmRh.Owner); UTF8Encoding utf8 = new UTF8Encoding(); byte[] nvData = utf8.GetBytes(uri); // Open the TPM Tpm2Device tpmDevice = new TbsDevice(); tpmDevice.Connect(); using (var tpm = new Tpm2(tpmDevice)) { // Define the store tpm.NvDefineSpace(ownerHandle, Array.Empty <byte>(), new NvPublic(nvHandle, TpmAlgId.Sha256, NvAttr.Authwrite | NvAttr.Authread | NvAttr.NoDa, Array.Empty <byte>(), (ushort)nvData.Length)); // Write the store tpm.NvWrite(nvHandle, nvHandle, nvData, 0); } }
static void ReadPcr() { Console.WriteLine("\nPCR sample started."); using (Tpm2Device tpmDevice = new TbsDevice()) { tpmDevice.Connect(); using (var tpm = new Tpm2(tpmDevice)) { var valuesToRead = new PcrSelection[] { new PcrSelection(TpmAlgId.Sha1, new uint[] { 1, 2 }) }; PcrSelection[] valsRead; Tpm2bDigest[] values; tpm.PcrRead(valuesToRead, out valsRead, out values); if (valsRead[0] != valuesToRead[0]) { Console.WriteLine("Unexpected PCR-set"); } var pcr1 = new TpmHash(TpmAlgId.Sha1, values[0].buffer); Console.WriteLine("PCR1: " + pcr1); var dataToExtend = new byte[] { 0, 1, 2, 3, 4 }; tpm.PcrEvent(TpmHandle.Pcr(1), dataToExtend); tpm.PcrRead(valuesToRead, out valsRead, out values); } } }
} //NVCounter internal static void CreateTwoPrimaries(Tpm2 tpm) { var data = Encoding.UTF8.GetBytes("hello world"); var handle1 = KeyHelpers.CreatePrimaryRsaKey(tpm, null, null, null, out TpmPublic key); IAsymSchemeUnion decScheme = new SchemeOaep(TpmAlgId.Sha1); var cipher = tpm.RsaEncrypt(handle1, data, decScheme, null); byte[] decrypted1 = tpm.RsaDecrypt(handle1, cipher, decScheme, null); var decyyptedData = Encoding.UTF8.GetString(decrypted1); var pub = tpm.ReadPublic(handle1, out byte[] name, out byte[] qn); var enc = KeyHelpers.CreateEncryptionDecryptionKey(tpm, handle1); tpm._ExpectResponses(TpmRc.Success, TpmRc.TbsCommandBlocked); var cipher2 = tpm.EncryptDecrypt(enc, 1, TpmAlgId.None, data, data, out byte[] test2); tpm.FlushContext(handle1); var handle2 = KeyHelpers.CreatePrimary(tpm, out TpmPublic key3); //, seed: new byte[] { 22, 123, 22, 1, 33 }); tpm.FlushContext(handle2); }
/// <summary> /// Releases the unmanaged resources used by the SecurityProviderTpmHsm and optionally disposes of the managed resources. /// </summary> /// <param name="disposing">true to release both managed and unmanaged resources; false to releases only unmanaged resources.</param> protected override void Dispose(bool disposing) { if (_disposed) { return; } if (Logging.IsEnabled) { Logging.Info(this, "Disposing"); } if (disposing) { // _tpmDevice is owned by _tpm2, which will disposed it, but not if it is null if (_tpm2 == null) { _tpmDevice?.Dispose(); _tpmDevice = null; } _tpm2.Dispose(); _tpm2 = null; } _disposed = true; }
public static void SaveValueIntoTpm(int address, byte[] data, int length) { Tpm2Device tpmDevice; if (System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.Windows)) { tpmDevice = new TbsDevice(); } else { tpmDevice = new LinuxTpmDevice(); } tpmDevice.Connect(); var tpm = new Tpm2(tpmDevice); var ownerAuth = new AuthValue(); TpmHandle nvHandle = TpmHandle.NV(address); tpm[ownerAuth]._AllowErrors().NvUndefineSpace(TpmHandle.RhOwner, nvHandle); AuthValue nvAuth = authValue; var nvPublic = new NvPublic(nvHandle, TpmAlgId.Sha1, NvAttr.Authwrite | NvAttr.Authread, new byte[0], (ushort)length); tpm[ownerAuth].NvDefineSpace(TpmHandle.RhOwner, nvAuth, nvPublic); tpm[nvAuth].NvWrite(nvHandle, nvHandle, data, 0); tpm.Dispose(); }
internal static TpmHandle CreateEncryptionDecryptionKey(Tpm2 tpm, TpmHandle parent) { var sensCreate = new SensitiveCreate(null, null); var sym = new SymDefObject(TpmAlgId.Aes, 128, TpmAlgId.Cfb); var pub = new TpmPublic(TpmAlgId.Sha256, ObjectAttr.Decrypt | ObjectAttr.UserWithAuth, null, sym, new Tpm2bDigestSymcipher()); TssObject swKey = TssObject.Create(pub); var innerWrapKey = sym == null ? null : SymCipher.Create(sym); byte[] name, qname; TpmPublic pubParent = tpm.ReadPublic(parent, out name, out qname); byte[] encSecret; TpmPrivate dupBlob = swKey.GetDuplicationBlob(pubParent, innerWrapKey, out encSecret); TpmPrivate privImp = tpm.Import(parent, innerWrapKey, swKey.Public, dupBlob, encSecret, sym ?? new SymDefObject()); TpmHandle hKey = tpm.Load(parent, privImp, swKey.Public) .SetAuth(swKey.Sensitive.authValue); return(hKey); }
/// <summary> /// This sample shows the use of HMAC sessions to authorize TPM actions. /// HMAC sessions may be bound/unbound and seeded/unseeded. This sample /// illustrates an unseeded and unbound session. /// </summary> /// <param name="tpm">Reference to the TPM object.</param> static void HmacUnboundUnseeded(Tpm2 tpm) { // // Create a hash-sequence with a random authorization value // TpmHandle hashHandle = tpm.HashSequenceStart(AuthValue.FromRandom(8), TpmAlgId.Sha256); // // Commands with the Ex modifier are library-provided wrappers // around TPM functions to make programming easier. This version // of StartAuthSessionEx calls StartAuthSession configured to // create an unbound and unseeded auth session with the auth-value // provided here. // AuthSession s0 = tpm.StartAuthSessionEx(TpmSe.Hmac, TpmAlgId.Sha256); // // The following calls show the use of the HMAC session in authorization. // The session to use is communicated as a parameter in the [] overloaded // function and the auth-value is that set during HMAC session creation. // It picks up the appropriate auth value from the handle used in the command // (hashHandle in this case). // TkHashcheck validate; tpm[s0].SequenceUpdate(hashHandle, new byte[] { 0, 2, 1 }); byte[] hashedData = tpm[s0].SequenceComplete(hashHandle, new byte[] { 2, 3, 4 }, TpmRh.Owner, out validate); Console.WriteLine("Hashed data (HMAC authorized sequence): " + BitConverter.ToString(hashedData)); tpm.FlushContext(s0); }
public static void PowerCycle(Tpm2 tpm, Su shutdownMode, Su startupMode) { tpm._AllowErrors() .Shutdown(shutdownMode); tpm._GetUnderlyingDevice().PowerCycle(); tpm.Startup(startupMode); }
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 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> /// Initializes a new instance of the SecurityProviderTpmHsm class using the specified TPM module. /// </summary> /// <param name="registrationId">The Device Provisioning Service Registration ID.</param> /// <param name="tpm">The TPM device.</param> public SecurityProviderTpmHsm(string registrationId, Tpm2Device tpm) : base(registrationId) { _tpmDevice = tpm ?? throw new ArgumentNullException(nameof(tpm)); _tpmDevice.Connect(); _tpm2 = new Tpm2(_tpmDevice); CacheEkAndSrk(); if (Logging.IsEnabled) { Logging.Associate(this, _tpm2); Logging.Associate(_tpm2, _tpmDevice); #if DEBUG _tpm2._SetTraceCallback((byte[] inBuffer, byte[] outBuffer) => { if (Logging.IsEnabled) { Logging.Info(this, $"TPM data: {Logging.GetHashCode(_tpm2)}"); Logging.DumpBuffer(_tpm2, inBuffer, nameof(inBuffer)); Logging.DumpBuffer(_tpm2, outBuffer, nameof(outBuffer)); } }); #endif } }
} // Pcrs /// <summary> /// Creates a primary RSA storage key in the storage hierarchy and returns its /// handle. The caller can provide an auth value and additional entropy for /// the key derivation (primary keys are deterministically derived by the TPM /// from an internal primary seed value unique for each hierarchy). /// The caller is responsible for disposing of the returned key handle. /// </summary> /// <param name="tpm">TPM instance to use</param> /// <param name="auth">Optional auth value to be associated with the created key.</param> /// <param name="seed">Optional entropy that may be used to create different primary kyes with exactly the same template.</param> /// <returns></returns> static TpmHandle CreateRsaPrimaryStorageKey(Tpm2 tpm, byte[] auth = null, byte[] seed = null) { TpmPublic newKeyPub; return(CreateRsaPrimaryStorageKey(tpm, out newKeyPub, seed, auth)); }
internal static TpmHandle CreatePrimary(Tpm2 tpm, out TpmPublic newKeyPub, byte[] auth = null, byte[] seed = null) { var sensCreate = new SensitiveCreate(auth, null); var parms = new TpmPublic(TpmAlgId.Sha256, // Name algorithm ObjectAttr.Restricted | ObjectAttr.Decrypt | // Storage key ObjectAttr.FixedParent | ObjectAttr.FixedTPM | // Non-duplicable ObjectAttr.UserWithAuth | ObjectAttr.SensitiveDataOrigin, null, // No policy // No signing or decryption scheme, and non-empty symmetric // specification (even when it is an asymmetric key) new RsaParms(new SymDefObject(TpmAlgId.Aes, 128, TpmAlgId.Cfb), null, 2048, 0), new Tpm2bPublicKeyRsa(seed) // Additional entropy for key derivation ); CreationData creationData; TkCreation creationTicket; byte[] creationHash; var handle = tpm.CreatePrimary(TpmRh.Owner, // In storage hierarchy sensCreate, // Auth value CreateDecryptionKey(), // Key template // // The following parameters influence the creation of the // creation-ticket. They are not used in this sample // null, // Null outsideInfo new PcrSelection[0], // Not PCR-bound out newKeyPub, // Our outs out creationData, out creationHash, out creationTicket); return(handle); }
void DuplicateImportRsaSample(Tpm2 tpm, TestContext testCtx) { TpmAlgId nameAlg = Substrate.Random(TpmCfg.HashAlgs); var policy = new PolicyTree(nameAlg); policy.SetPolicyRoot(new TpmPolicyCommand(TpmCc.Duplicate)); var inPub = new TpmPublic(nameAlg, ObjectAttr.Sign | ObjectAttr.AdminWithPolicy | ObjectAttr.SensitiveDataOrigin, policy.GetPolicyDigest(), new RsaParms(new SymDefObject(), new SchemeRsassa(Substrate.Random(TpmCfg.HashAlgs)), Substrate.Random(TpmCfg.RsaKeySizes), 0), new Tpm2bPublicKeyRsa()); TpmHandle hKey = Substrate.CreateAndLoad(tpm, inPub, out TpmPublic pub); // Duplicate TpmPrivate priv = TpmHelper.GetPlaintextPrivate(tpm, hKey, policy); tpm.FlushContext(hKey); // Import TpmPrivate privImp = tpm.Import(Substrate.LoadRsaPrimary(tpm), null, pub, priv, null, new SymDefObject()); } // SimpleDuplicateImportRsaSample
} // SimpleDuplicateImportRsaSample TssObject ImportExternalRsaKey(Tpm2 tpm, TpmHandle hParent, int keySizeInBits, IAsymSchemeUnion scheme, byte[] publicPart, byte[] privatePart, ObjectAttr keyAttrs, byte[] authVal = null, byte[] policyDigest = null) { TpmAlgId sigHashAlg = TpmHelper.GetSchemeHash(scheme), nameAlg = sigHashAlg; // TPM signing key template with the actual public key bits var inPub = new TpmPublic(nameAlg, keyAttrs, policyDigest, new RsaParms(new SymDefObject(), scheme as IAsymSchemeUnion, (ushort)keySizeInBits, 0), new Tpm2bPublicKeyRsa(publicPart)); // Wrap the key in a TSS helper class TssObject swKey = TssObject.Create(inPub, authVal, privatePart); // Get a key duplication blob in TPM 2.0 compatibale format TpmPrivate dupBlob = swKey.GetPlaintextDuplicationBlob(); // Importing a duplication blob creates a new TPM private key blob protected // with its new parent key. swKey.Private = tpm.Import(hParent, null, swKey.Public, dupBlob, null, new SymDefObject()); return(swKey); } // ImportExternalRsaKey
void ExternalKeyImportSample(Tpm2 tpm, TestContext testCtx) { // Create a software key (external to any TPM). int keySize = 2048; var externalRsaKey = new RawRsa(keySize); // When an external key comes from a cert, one would need to extract the key size and // byte buffers representing public and private parts of the key from the cert, an use // them directly in the call to ImportExternalRsaKey() below (i.e. no RawRsa object is // necessary). // Signing scheme to use (it may come from the key's cert) TpmAlgId sigHashAlg = Substrate.Random(TpmCfg.HashAlgs); var sigScheme = new SchemeRsassa(sigHashAlg); // An arbitrary external key would not have TPM key attributes associated with it. // Yet some of them may be inferred from the cert based on the declared key purpose // (ObjectAttr.Sign below). The others are defined by the intended TPM key usage // scenarios, e.g. ObjectAttr.UserWithAuth tells TPM to allow key usage authorization // using an auth value (random byte buffer) in a password or an HMAC session. ObjectAttr keyAttrs = ObjectAttr.Sign | ObjectAttr.UserWithAuth; // Generate an auth value for the imported matching in strength the signing scheme byte[] authVal = Substrate.RandomAuth(sigHashAlg); // We need a storage key to use as a parent of the imported key. // The following helper creates an RSA primary storage key. TpmHandle hParent = Substrate.CreateRsaPrimary(tpm); TssObject importedKey = ImportExternalRsaKey(tpm, hParent, keySize, sigScheme, externalRsaKey.Public, externalRsaKey.Private, keyAttrs, authVal); // Now we can load the newly imported key into the TPM, ... TpmHandle hImportedKey = tpm.Load(hParent, importedKey.Private, importedKey.Public); // ... let the TSS know the auth value associated with this handle, ... hImportedKey.SetAuth(authVal); // ... and use it to sign something to check if import was OK TpmHash toSign = TpmHash.FromRandom(sigHashAlg); ISignatureUnion sig = tpm.Sign(hImportedKey, toSign, null, new TkHashcheck()); // Verify that the signature is correct using the public part of the imported key bool sigOk = importedKey.Public.VerifySignatureOverHash(toSign, sig); testCtx.Assert("Signature.OK", sigOk); // Cleanup tpm.FlushContext(hImportedKey); // The parent key handle can be flushed immediately after it was used in the Load() command tpm.FlushContext(hParent); // Imported private/public key pair (in the TssObject) can be stored on disk, in the cloud, // etc. (no additional protection is necessary), and loaded into the TPM as above whenever // the key is needed. // Alternatively the key can be persisted in the TPM using the EvictControl() command } // ExternalKeyImportSample
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 static void PrintCommandss(Tpm2 tpm) { try { ICapabilitiesUnion caps; tpm.GetCapability(Cap.TpmProperties, (uint)Pt.TotalCommands, 1, out caps); tpm.GetCapability(Cap.Commands, (uint)TpmCc.First, TpmCc.Last - TpmCc.First + 1, out caps); var commands = (CcaArray)caps; Console.WriteLine("Supported commands:"); List <TpmCc> implementedCc = new List <TpmCc>(); foreach (var attr in commands.commandAttributes) { var commandCode = (TpmCc)((uint)attr & 0x0000FFFFU); implementedCc.Add(commandCode); Console.WriteLine(" {0}", commandCode.ToString()); } Console.WriteLine("Commands from spec not implemented:"); foreach (var cc in Enum.GetValues(typeof(TpmCc))) { if (!implementedCc.Contains((TpmCc)cc)) { Console.WriteLine(" {0}", cc.ToString()); } } } catch (Exception ex) { Console.WriteLine(ex); } }
/// <summary> /// Gets the identifier of the device /// </summary> /// <returns></returns> public string GetHardwareDeviceId() { TpmHandle srkHandle = new TpmHandle(TPM_20_SRK_HANDLE); try { string hardwareDeviceId; // Open the TPM Tpm2Device tpmDevice = new TbsDevice(); tpmDevice.Connect(); using (var tpm = new Tpm2(tpmDevice)) { // Read the URI from the TPM TpmPublic srk = tpm.ReadPublic(srkHandle, out byte[] name, out byte[] qualifiedName); // Calculate the hardware device id for this logical device byte[] deviceId = CryptoLib.HashData(TpmAlgId.Sha256, BitConverter.GetBytes(logicalDeviceId), name); // Produce the output string hardwareDeviceId = string.Join(string.Empty, deviceId.Select(b => b.ToString("x2"))); } return(hardwareDeviceId); } catch { } return(string.Empty); }
void TestFailureMode(Tpm2 tpm, TestContext testCtx) { tpm._GetUnderlyingDevice().TestFailureMode(); tpm._ExpectError(TpmRc.Failure) .SelfTest(1); TpmRc testResult = TpmRc.None; byte[] outData = tpm.GetTestResult(out testResult); testCtx.Assert("TestResult", testResult == TpmRc.Failure); testCtx.Assert("OutData", outData != null && outData.Length > 0); // Make sure that selected capabilities can be retrieved even when TPM is in failure mode Tpm2.GetProperty(tpm, Pt.Manufacturer); Tpm2.GetProperty(tpm, Pt.VendorString1); Tpm2.GetProperty(tpm, Pt.VendorTpmType); Tpm2.GetProperty(tpm, Pt.FirmwareVersion1); // Check if other commands fail as expected while in failure mode. tpm._ExpectError(TpmRc.Failure) .GetRandom(8); // Bring TPM back to normal. tpm._GetUnderlyingDevice().PowerCycle(); tpm.Startup(Su.Clear); } // TestFailureMode
/// <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); }
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); }
void TestSerialization(Tpm2 tpm, TestContext testCtx) { // test library serialization (not a TPM test) TpmAlgId hashAlg = Substrate.Random(TpmCfg.HashAlgs); // make some moderately complicated TPM structures var inPub = new TpmPublic(hashAlg, ObjectAttr.Sign | ObjectAttr.FixedParent | ObjectAttr.FixedTPM | ObjectAttr.UserWithAuth | ObjectAttr.SensitiveDataOrigin, null, new RsaParms(new SymDefObject(), new SchemeRsassa(hashAlg), Substrate.Random(TpmCfg.RsaKeySizes), 0), new Tpm2bPublicKeyRsa()); TpmPublic pub; TpmHandle hKey = Substrate.CreateAndLoad(tpm, inPub, out pub); TpmHash hashToSign = TpmHash.FromRandom(hashAlg); var proof = new TkHashcheck(TpmRh.Null, null); var sig = tpm.Sign(hKey, hashToSign, new SchemeRsassa(hashAlg), proof); tpm.FlushContext(hKey); // Simple TPM-hash to/from JSON TpmHash h = TpmHash.FromString(hashAlg, "hello"); MemoryStream s2 = new MemoryStream(); DataContractJsonSerializer ser2 = new DataContractJsonSerializer(typeof(TpmHash)); ser2.WriteObject(s2, h); s2.Flush(); string jsonString2 = Encoding.ASCII.GetString(s2.ToArray()); TpmHash h2 = (TpmHash)ser2.ReadObject(new MemoryStream(s2.ToArray())); testCtx.AssertEqual("JSON.Simple", h, h2); // JSON more complex - MemoryStream s = new MemoryStream(); DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(TpmPublic)); ser.WriteObject(s, pub); s.Flush(); string jsonString = Encoding.ASCII.GetString(s.ToArray()); TpmPublic reconstruct = (TpmPublic)ser.ReadObject(new MemoryStream(s.ToArray())); testCtx.AssertEqual("JSON.Complex", pub, reconstruct); // XML s = new MemoryStream(); DataContractSerializer s4 = new DataContractSerializer(typeof(TpmPublic)); s4.WriteObject(s, pub); s.Flush(); string xmlString = Encoding.ASCII.GetString(s.ToArray()); TpmPublic rec4 = (TpmPublic)s4.ReadObject(new MemoryStream(s.ToArray())); testCtx.AssertEqual("XML.Complex", pub, rec4, s4); } // TestSerialization
public static bool AreAnySlotsFull(Tpm2 tpm) { var tagActiveSession = TpmHelpers.GetEnumerator <Ht>("ActiveSession", "SavedSession"); return(TpmHelper.GetLoadedEntities(tpm, Ht.Transient).Length != 0 || TpmHelper.GetLoadedEntities(tpm, Ht.LoadedSession).Length != 0 || TpmHelper.GetLoadedEntities(tpm, Ht.LoadedSession).Length != 0); }
internal static byte[] RsaDecrypt(Tpm2 tpm, byte[] data) { var handle1 = KeyHelpers.CreatePrimaryRsaKey(tpm, null, new byte[] { 2 }, new byte[] { 1, 2, 3 }, out TpmPublic key); byte[] decrypted1 = tpm.RsaDecrypt(handle1, data, decScheme, null); tpm.FlushContext(handle1); return(decrypted1); }
/// <summary> /// Constructor creating an instance using the specified TPM module. /// </summary> /// <param name="registrationId">The Device Provisioning Service Registration ID.</param> /// <param name="tpm">The TPM device.</param> public SecurityClientTpm(string registrationId, Tpm2Device tpm) : base(registrationId) { _tpmDevice = tpm; _tpmDevice.Connect(); _tpm2 = new Tpm2(_tpmDevice); CacheEkAndSrk(); }
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); }
static TpmHandle CreateRsaPrimaryKey(Tpm2 tpm, bool isSimulator) { if (isSimulator) { tpm.DictionaryAttackParameters(TpmHandle.RhLockout, 1000, 10, 1); tpm.DictionaryAttackLockReset(TpmHandle.RhLockout); } // // First member of SensitiveCreate contains auth value of the key // var sensCreate = new SensitiveCreate(new byte[] { 0xa, 0xb, 0xc }, null); TpmPublic parms = new TpmPublic( TpmAlgId.Sha1, ObjectAttr.Restricted | ObjectAttr.Decrypt | ObjectAttr.FixedParent | ObjectAttr.FixedTPM | ObjectAttr.UserWithAuth | ObjectAttr.SensitiveDataOrigin, null, new RsaParms( new SymDefObject(TpmAlgId.Aes, 128, TpmAlgId.Cfb), new NullAsymScheme(), 2048, 0), new Tpm2bPublicKeyRsa()); byte[] outsideInfo = Globs.GetRandomBytes(8); var creationPcr = new PcrSelection(TpmAlgId.Sha1, new uint[] { 0, 1, 2 }); TpmPublic pubCreated; CreationData creationData; TkCreation creationTicket; byte[] creationHash; Console.WriteLine("Automatic authorization of TpmRh.Owner."); // // An auth session is added automatically to authorize access to the permanent // handle TpmHandle.RhOwner. // // Note that if the TPM is not a simulator and not cleared, you need to // assign the corresponding auth value to the tpm.OwnerAuth property of // the given Tpm2 object. // TpmHandle h = tpm.CreatePrimary(TpmRh.Owner, sensCreate, parms, outsideInfo, new PcrSelection[] { creationPcr }, out pubCreated, out creationData, out creationHash, out creationTicket); Console.WriteLine("Primary RSA storage key created."); return(h); }
public override void Open(string location) { lock (m_lock) { base.Open(location); m_tpmDevice.Connect(); m_tpm = new Tpm2(m_tpmDevice); } }
public static TpmHandle[] GetAllLoadedEntities(Tpm2 tpm) { TpmHandle[] h0 = GetLoadedEntities(tpm, Ht.Transient); TpmHandle[] h1 = GetLoadedEntities(tpm, Ht.LoadedSession); TpmHandle[] h = new TpmHandle[h0.Length + h1.Length]; Array.Copy(h0, h, h0.Length); Array.Copy(h1, 0, h, h0.Length, h1.Length); return(h); }