public static void ConnectLocal() { using (Tpm2Device tpmDevice = new TbsDevice()) { tpmDevice.Connect(); } }
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); } }
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); }
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); } } }
/// <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); }
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); }
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); }
internal static TpmClient CreateDeviceClient() { Tpm2Device tpmDevice = new TbsDevice(); tpmDevice.Connect(); var tpm = new Tpm2(tpmDevice); TpmClient client = new TpmClient(tpmDevice, tpm); return(client); }
/// <summary> /// Funzione per la pulizia di una chiave e funzione HMAC precedentementi salvati nel TPM /// </summary> public static void CleanOldHmacKey() { // Apertura del TPM Tpm2Device tpmDevice = new TbsDevice(); tpmDevice.Connect(); var tpm = new Tpm2(tpmDevice); TpmHandle ownerHandle = new TpmHandle(TpmRh.Owner); TpmHandle nvHandle = new TpmHandle(AIOTH_PERSISTED_URI_INDEX + logicalDeviceId); TpmHandle hmacKeyHandle = new TpmHandle(AIOTH_PERSISTED_KEY_HANDLE + logicalDeviceId); // Undefine dello spazio utilizzato per la chiave HMAC tpm.NvUndefineSpace(ownerHandle, nvHandle); // Rimozione della funzione HMAC tpm.EvictControl(ownerHandle, hmacKeyHandle, hmacKeyHandle); }
/// <summary> /// Sign data using the key stored in the TPM. The signing is done inside the TPM to avoid exposing the key. /// This is similar to using <see cref="System.Security.Cryptography.SHA256CryptoServiceProvider"/> which /// uses <see cref="System.Security.Cryptography.HMACSHA256"/> inside. /// </summary> /// <param name="data"></param> /// <returns></returns> public byte[] Sign(byte[] data) { TpmHandle hmacKeyHandle = new TpmHandle(PERSISTED_KEY_HANDLE + logicalDeviceId); int dataIndex = 0; byte[] iterationBuffer, result = Array.Empty <byte>(); try { // Open the TPM Tpm2Device tpmDevice = new TbsDevice(); tpmDevice.Connect(); using (var tpm = new Tpm2(tpmDevice)) { if (data.Length <= 1024) { // Calculate the HMAC in one shot result = tpm.Hmac(hmacKeyHandle, data, TpmAlgId.Sha256); } else { // Start the HMAC sequence TpmHandle hmacHandle = tpm.HmacStart(hmacKeyHandle, Array.Empty <byte>(), TpmAlgId.Sha256); while (data.Length > dataIndex + 1024) { // Repeat to update the hmac until we only hace <=1024 bytes left iterationBuffer = new byte[1024]; Array.Copy(data, dataIndex, iterationBuffer, 0, 1024); tpm.SequenceUpdate(hmacHandle, iterationBuffer); dataIndex += 1024; } // Finalize the hmac with the remainder of the data iterationBuffer = new byte[data.Length - dataIndex]; Array.Copy(data, dataIndex, iterationBuffer, 0, data.Length - dataIndex); result = tpm.SequenceComplete(hmacHandle, iterationBuffer, TpmHandle.RhNull, out TkHashcheck nullChk); } } } catch { } return(result); }
public void Destroy() { TpmHandle nvHandle = new TpmHandle(AIOTH_PERSISTED_URI_INDEX + logicalDeviceId); TpmHandle ownerHandle = new TpmHandle(TpmRh.Owner); TpmHandle hmacKeyHandle = new TpmHandle(AIOTH_PERSISTED_KEY_HANDLE + logicalDeviceId); // Open the TPM Tpm2Device tpmDevice = new TbsDevice(); tpmDevice.Connect(); var tpm = new Tpm2(tpmDevice); // Destyroy the URI tpm.NvUndefineSpace(ownerHandle, nvHandle); // Destroy the HMAC key tpm.EvictControl(ownerHandle, hmacKeyHandle, hmacKeyHandle); // Dispose of the TPM tpm.Dispose(); }
internal NetProxy(DeviceType theDeviceType, int listeningPort, string tpmHost, int tpmPort) { TpmHost = tpmHost; TpmPort = tpmPort; tpmEndPointInfo = 0; TheDeviceType = theDeviceType; // make the appropriate devices to connect to the TPM if (TheDeviceType == DeviceType.Tbs) { // todo: Check if TPM is in the raw mode. tpmEndPointInfo |= (int)TpmEndPointInfo.UsesTbs; tbsDevice = new TbsDevice(); try { tbsDevice.Connect(); } catch (Exception e) { Console.WriteLine("Failed to connect to the TBS context. Error was: " + e.ToString()); return; } } // The proxy needs to relay commands on two sockets: one for the platform // and one for the rest of the commands. These need to operate // independently commandListener = new TcpListener(IPAddress.Any, listeningPort); commandListener.Start(); platformListener = new TcpListener(IPAddress.Any, listeningPort + 1); platformListener.Start(); Console.WriteLine("Proxy is waiting for connections..."); // Start a second threads to relay TCP commands to the device. The two threads // access disjoint state. Thread t = new Thread(PlatformServerThread); t.Start(); // and start the second thread CommandServerThread(); }
/// <summary> /// Provision the key in the TPM /// </summary> /// <param name="key">the access key</param> public void Provision(byte[] key) { TpmHandle ownerHandle = new TpmHandle(TpmRh.Owner); TpmHandle hmacKeyHandle = new TpmHandle(PERSISTED_KEY_HANDLE + logicalDeviceId); TpmHandle srkHandle = new TpmHandle(TPM_20_SRK_HANDLE); // Open the TPM Tpm2Device tpmDevice = new TbsDevice(); tpmDevice.Connect(); using (var tpm = new Tpm2(tpmDevice)) { #pragma warning disable IDE0059 // Value assigned to symbol is never used // Import the HMAC key under the SRK TpmPrivate hmacPrv = tpm.Create(srkHandle, new SensitiveCreate(Array.Empty <byte>(), key), new TpmPublic(TpmAlgId.Sha256, ObjectAttr.UserWithAuth | ObjectAttr.NoDA | ObjectAttr.Sign, Array.Empty <byte>(), new KeyedhashParms(new SchemeHmac(TpmAlgId.Sha256)), new Tpm2bDigestKeyedhash()), Array.Empty <byte>(), Array.Empty <PcrSelection>(), out TpmPublic hmacPub, out CreationData creationData, out byte[] creationhash, out TkCreation ticket); #pragma warning restore IDE0059 // Value assigned to symbol is never used // 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); } }
/// <summary> /// Executes the hashing functionality. After parsing arguments, the /// function connects to the selected TPM device and invokes the TPM /// commands on that connection. /// </summary> /// <param name="args">Arguments to this program.</param> static void Main(string[] args) { try { // // Create the device according to the selected connection. // Tpm2Device tpmDevice = new TbsDevice(); // // Connect to the TPM device. This function actually establishes the // connection. // tpmDevice.Connect(); // // Pass the device object used for communication to the TPM 2.0 object // which provides the command interface. // var tpm = new Tpm2(tpmDevice); // // Run test // NvReadWriteWithOwnerAuth(tpm); // // Clean up. // tpm.Dispose(); } catch (Exception e) { Console.WriteLine("Exception occurred: {0}", e.Message); Console.WriteLine("{0}", e.StackTrace); } Console.WriteLine("Press Any Key to continue."); Console.ReadLine(); }
private void button_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e) { try { Tpm2Device tpmDevice = new TbsDevice(); tpmDevice.Connect(); // // Pass the device object used for communication to the TPM 2.0 object // which provides the command interface. // var tpm = new Tpm2(tpmDevice); NVReadWrite(tpm); NVCounter(tpm); tpm.Dispose(); } catch (Exception ex) { this.textBlock.Text = "Exception occurred: " + ex.Message; } }
public string GetHardwareDeviceId() { TpmHandle srkHandle = new TpmHandle(SRK_HANDLE); string hardwareDeviceId = ""; Byte[] name; Byte[] qualifiedName; try { // Open the TPM Tpm2Device tpmDevice = new TbsDevice(); tpmDevice.Connect(); var tpm = new Tpm2(tpmDevice); // Read the URI from the TPM TpmPublic srk = tpm.ReadPublic(srkHandle, out name, out qualifiedName); // Dispose of the TPM tpm.Dispose(); } catch { return(hardwareDeviceId); } // Calculate the hardware device id for this logical device byte[] deviceId = CryptoLib.HashData(TpmAlgId.Sha256, BitConverter.GetBytes(logicalDeviceId), name); // Produce the output string foreach (byte n in deviceId) { hardwareDeviceId += n.ToString("x2"); } return(hardwareDeviceId); }
public Byte[] SignHmac(Byte[] dataToSign) { TpmHandle hmacKeyHandle = new TpmHandle(AIOTH_PERSISTED_KEY_HANDLE + logicalDeviceId); int dataIndex = 0; Byte[] iterationBuffer; Byte[] hmac = { }; if (dataToSign.Length <= 1024) { try { // Open the TPM Tpm2Device tpmDevice = new TbsDevice(); tpmDevice.Connect(); var tpm = new Tpm2(tpmDevice); // Calculate the HMAC in one shot hmac = tpm.Hmac(hmacKeyHandle, dataToSign, TpmAlgId.Sha256); // Dispose of the TPM tpm.Dispose(); } catch { return(hmac); } } else { try { // Open the TPM Tpm2Device tpmDevice = new TbsDevice(); tpmDevice.Connect(); var tpm = new Tpm2(tpmDevice); // Start the HMAC sequence Byte[] hmacAuth = new byte[0]; TpmHandle hmacHandle = tpm.HmacStart(hmacKeyHandle, hmacAuth, TpmAlgId.Sha256); while (dataToSign.Length > dataIndex + 1024) { // Repeat to update the hmac until we only hace <=1024 bytes left iterationBuffer = new Byte[1024]; Array.Copy(dataToSign, dataIndex, iterationBuffer, 0, 1024); tpm.SequenceUpdate(hmacHandle, iterationBuffer); dataIndex += 1024; } // Finalize the hmac with the remainder of the data iterationBuffer = new Byte[dataToSign.Length - dataIndex]; Array.Copy(dataToSign, dataIndex, iterationBuffer, 0, dataToSign.Length - dataIndex); TkHashcheck nullChk; hmac = tpm.SequenceComplete(hmacHandle, iterationBuffer, TpmHandle.RhNull, out nullChk); // Dispose of the TPM tpm.Dispose(); } catch { return(hmac); } } return(hmac); }
/// <summary> /// This sample demonstrates the creation of a signing "primary" key and use of this /// key to sign data, and use of the TPM and Tpm2Lib to validate the signature. /// </summary> /// <param name="args">Arguments to this program.</param> static void Main(string[] args) { string tpmDeviceName; // // Parse the program arguments. If the wrong arguments are given or // are malformed, then instructions for usage are displayed and // the program terminates. // if (!ParseArguments(args, out tpmDeviceName)) { WriteUsage(); return; } try { // // Create the device according to the selected connection. // Tpm2Device tpmDevice; switch (tpmDeviceName) { case DeviceSimulator: tpmDevice = new TcpTpmDevice(DefaultSimulatorName, DefaultSimulatorPort); break; case DeviceWinTbs: tpmDevice = new TbsDevice(); break; default: throw new Exception("Unknown device selected."); } // // Connect to the TPM device. This function actually establishes the connection. // tpmDevice.Connect(); // // Pass the device object used for communication to the TPM 2.0 object // which provides the command interface. // var tpm = new Tpm2(tpmDevice); if (tpmDevice is TcpTpmDevice) { // // If we are using the simulator, we have to do a few things the // firmware would usually do. These actions have to occur after // the connection has been established. // tpmDevice.PowerCycle(); tpm.Startup(Su.Clear); } // // Run individual tests. // SimplePolicy(tpm); PolicyOr(tpm); PolicySerialization(); PolicyEvaluationWithCallback(tpm); PolicyEvaluationWithCallback2(tpm); SamplePolicySerializationAndCallbacks(tpm); // // Clean up. // tpm.Dispose(); } catch (TpmException e) { // // If a command fails because an unexpected return code is in the response, // i.e., TPM returns an error code where success is expected or success // where an error code is expected. Or if the response is malformed, then // the unmarshaling code will throw a TPM exception. // The Error string will contain a description of the return code. Usually the // return code will be a known TPM return code. However, if using the TPM through // TBS, TBS might encode internal error codes into the response code. For instance // a return code of 0x80280400 indicates that a command is blocked by TBS. This // error code is also returned if the command is not implemented by the TPM. // // You can see the information included in the TPM exception by removing the // checks for available TPM commands above and running the sample on a TPM // without the required commands. // Console.WriteLine("TPM exception occurred: {0}", e.ErrorString); Console.WriteLine("Call stack: {0}", e.StackTrace); } catch (Exception e) { Console.WriteLine("Exception occurred: {0}", e.Message); } Console.WriteLine("Press Any Key to continue."); Console.ReadLine(); }
public string GetHardwareDeviceId() { TpmHandle srkHandle = new TpmHandle(SRK_HANDLE); string hardwareDeviceId = ""; Byte[] name; Byte[] qualifiedName; try { // Open the TPM Tpm2Device tpmDevice = new TbsDevice(); tpmDevice.Connect(); var tpm = new Tpm2(tpmDevice); // Read the URI from the TPM TpmPublic srk = tpm.ReadPublic(srkHandle, out name, out qualifiedName); // Dispose of the TPM tpm.Dispose(); } catch { return hardwareDeviceId; } // Calculate the hardware device id for this logical device byte[] deviceId = CryptoLib.HashData(TpmAlgId.Sha256, BitConverter.GetBytes(logicalDeviceId), name); // Produce the output string foreach (byte n in deviceId) { hardwareDeviceId += n.ToString("x2"); } return hardwareDeviceId; }
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; }
static void Main(string[] args) { Console.WriteLine("Hello World!"); using (var client = TpmClient.CreateSimulatorClient()) { var helloWorld = Encoding.UTF8.GetBytes("Hello World"); var cipher = RsaExamples.RsaEncrypt(client.Tpm, helloWorld); var decipher = RsaExamples.RsaDecrypt(client.Tpm, cipher); var helloWorld2 = Encoding.UTF8.GetString(decipher); return; Examples.PrintCommandss(client.Tpm); Examples.CreateTwoPrimaries(client.Tpm); Examples.EncryptDecrypt(client.Tpm); return; var r = client.Tpm.GetRandom(10); Console.WriteLine(client.Tpm._GetUnderlyingDevice().HasRM()); CreateRsaPrimaryKey(client.Tpm, false); Examples.NVReadWrite(client.Tpm); Examples.NVCounter(client.Tpm); Examples.AvailablePCRBanks(client.Tpm); Examples.PrintAlgorithms(client.Tpm); } return; using (var client = TpmClient.CreateDeviceClient()) { Examples.AvailablePCRBanks(client.Tpm); Examples.PrintAlgorithms(client.Tpm); Examples.PrintCommandss(client.Tpm); } return; Sign(); return; var data = Encoding.UTF8.GetBytes("Hello World"); Examples.SaveValueIntoTpm(3001, data, data.Length, _authValue); Examples.ReadValueFromTpm(3001, data.Length, _authValue); return; Examples.GetHardwareDeviceName(); return; Examples.GetDeviceId(); return; Examples.ConnectLocal(); Examples.ConnectSimulator(); using (var device = Examples.Connect(useSimulator)) { //Examples.AvailablePCRBanks(device); } return; ReadPcr(); Sign(); try { using (Tpm2Device tpmDevice = new TbsDevice()) { tpmDevice.Connect(); using (var tpm = new Tpm2(tpmDevice)) { ICapabilitiesUnion caps; tpm.GetCapability(Cap.Algs, 0, 1000, out caps); var algsx = (AlgPropertyArray)caps; Console.WriteLine("Supported algorithms:"); foreach (var alg in algsx.algProperties) { Console.WriteLine(" {0}", alg.alg.ToString()); } Console.WriteLine("Supported commands:"); 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; 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()); } } // // As an alternative: call GetCapabilities more than once to obtain all values // byte more; var firstCommandCode = (uint)TpmCc.First; do { more = tpm.GetCapability(Cap.Commands, firstCommandCode, 10, out caps); commands = (CcaArray)caps; // // Commands are sorted; getting the last element as it will be the largest. // uint lastCommandCode = (uint)commands.commandAttributes[commands.commandAttributes.Length - 1] & 0x0000FFFFU; firstCommandCode = lastCommandCode; } while (more == 1); // // Read PCR attributes. Cap.Pcrs returns the list of PCRs which are supported // in different PCR banks. The PCR banks are identified by the hash algorithm // used to extend values into the PCRs of this bank. // tpm.GetCapability(Cap.Pcrs, 0, 255, out caps); PcrSelection[] pcrs = ((PcrSelectionArray)caps).pcrSelections; Console.WriteLine(); Console.WriteLine("Available PCR banks:"); foreach (PcrSelection pcrBank in pcrs) { var sb = new StringBuilder(); sb.AppendFormat("PCR bank for algorithm {0} has registers at index:", pcrBank.hash); sb.AppendLine(); foreach (uint selectedPcr in pcrBank.GetSelectedPcrs()) { sb.AppendFormat("{0},", selectedPcr); } Console.WriteLine(sb); } // // Read PCR attributes. Cap.PcrProperties checks for certain properties of each PCR register. // tpm.GetCapability(Cap.PcrProperties, 0, 255, out caps); Console.WriteLine(); Console.WriteLine("PCR attributes:"); TaggedPcrSelect[] pcrProperties = ((TaggedPcrPropertyArray)caps).pcrProperty; foreach (TaggedPcrSelect pcrProperty in pcrProperties) { if ((PtPcr)pcrProperty.tag == PtPcr.None) { continue; } uint pcrIndex = 0; var sb = new StringBuilder(); sb.AppendFormat("PCR property {0} supported by these registers: ", (PtPcr)pcrProperty.tag); sb.AppendLine(); foreach (byte pcrBitmap in pcrProperty.pcrSelect) { for (int i = 0; i < 8; i++) { if ((pcrBitmap & (1 << i)) != 0) { sb.AppendFormat("{0},", pcrIndex); } pcrIndex++; } } Console.WriteLine(sb); } } } } catch (Exception ex) { Console.WriteLine(ex); } Console.ReadKey(); }
/// <summary> /// Funzione per la firma HMAC tramite TPM /// </summary> /// <param name="dataToAuth"></param> /// <returns></returns> public static Byte[] CalculateHmac(Byte[] dataToAuth) { TpmHandle hmacKeyHandle = new TpmHandle(AIOTH_PERSISTED_KEY_HANDLE + logicalDeviceId); int dataIndex = 0; Byte[] iterationBuffer; Byte[] hmac = { }; // Se i valori da firmare sono < 1024 byte if (dataToAuth.Length <= 1024) { try { // Apertura del TPM Tpm2Device tpmDevice = new TbsDevice(); tpmDevice.Connect(); var tpm = new Tpm2(tpmDevice); // Calcolo dell'HMAC tramite la funzione salvata in precedenza hmac = tpm.Hmac(hmacKeyHandle, dataToAuth, TpmAlgId.Sha256); // Dispose del TPM tpm.Dispose(); } catch (Exception ex) { Console.WriteLine(ex.Message); return(hmac); } } else { try { // Apertura del TPM Tpm2Device tpmDevice = new TbsDevice(); tpmDevice.Connect(); var tpm = new Tpm2(tpmDevice); // Inizio della sequenza HMAC Byte[] hmacAuth = new byte[0]; TpmHandle hmacHandle = tpm.HmacStart(hmacKeyHandle, hmacAuth, TpmAlgId.Sha256); // ciclo su tutti i dati da firmare a blocchi da 1024 byte while (dataToAuth.Length > dataIndex + 1024) { // Repeat to update the hmac until we only hace <=1024 bytes left iterationBuffer = new Byte[1024]; Array.Copy(dataToAuth, dataIndex, iterationBuffer, 0, 1024); // Caricamento dei dati nel tpm (calcolo parziale) tpm.SequenceUpdate(hmacHandle, iterationBuffer); dataIndex += 1024; } // Caricamento della parte finale iterationBuffer = new Byte[dataToAuth.Length - dataIndex]; Array.Copy(dataToAuth, dataIndex, iterationBuffer, 0, dataToAuth.Length - dataIndex); TkHashcheck nullChk; // Si finalizza l'HMAC con l'ultima parte dei dati hmac = tpm.SequenceComplete(hmacHandle, iterationBuffer, TpmHandle.RhNull, out nullChk); // Dispose del TPM tpm.Dispose(); } catch { return(hmac); } } return(hmac); }
/// <summary> /// Get the endorsement key from the TPM. If the key has not yet been set, a new one is generated /// </summary> /// <returns></returns> /// <remarks> /// Picked from https://github.com/Azure/azure-iot-sdk-csharp/blob/e1dd08eacd1caf58f3b318d8ad5ad94dde961d78/security/tpm/src/SecurityProviderTpmHsm.cs#L258-L324 /// </remarks> public static byte[] GetEndorsementKey() { TpmHandle ekHandle = new TpmHandle(TPM_20_EK_HANDLE); byte[] result = Array.Empty <byte>(); try { // Open the TPM Tpm2Device tpmDevice = new TbsDevice(); tpmDevice.Connect(); using (var tpm = new Tpm2(tpmDevice)) { // Read EK from the TPM, temporarily allowing errors TpmPublic ekPub = tpm. _AllowErrors() .ReadPublic(ekHandle, out byte[] name, out byte[] qualifiedName); // if the last command did not succeed, we do not have an endorsement key yet, so create it if (!tpm._LastCommandSucceeded()) { // Get the real EK ready. TpmPublic ekTemplate = new TpmPublic( TpmAlgId.Sha256, ObjectAttr.FixedTPM | ObjectAttr.FixedParent | ObjectAttr.SensitiveDataOrigin | ObjectAttr.AdminWithPolicy | ObjectAttr.Restricted | ObjectAttr.Decrypt, new byte[] { 0x83, 0x71, 0x97, 0x67, 0x44, 0x84, 0xb3, 0xf8, 0x1a, 0x90, 0xcc, 0x8d, 0x46, 0xa5, 0xd7, 0x24, 0xfd, 0x52, 0xd7, 0x6e, 0x06, 0x52, 0x0b, 0x64, 0xf2, 0xa1, 0xda, 0x1b, 0x33, 0x14, 0x69, 0xaa }, new RsaParms( new SymDefObject(TpmAlgId.Aes, 128, TpmAlgId.Cfb), new NullAsymScheme(), 2048, 0), new Tpm2bPublicKeyRsa(new byte[2048 / 8])); TpmHandle keyHandle = tpm.CreatePrimary( new TpmHandle(TpmHandle.RhEndorsement), new SensitiveCreate(), ekTemplate, Array.Empty <byte>(), Array.Empty <PcrSelection>(), out ekPub, out CreationData creationData, out byte[] creationHash, out TkCreation creationTicket); tpm.EvictControl(TpmHandle.RhOwner, keyHandle, ekHandle); tpm.FlushContext(keyHandle); } // Get the EK representation result = ekPub.GetTpm2BRepresentation(); } } catch { } return(result); }
/// <summary> /// Funzione per il salvataggio della chiave privata da utilizzare per firmare con HMAC tramite TPM /// </summary> /// <param name="encodedHmacKey"></param> public static void SaveHmacKey(string encodedHmacKey) { // Definizione area di memoria non volatile nel TPM TpmHandle nvHandle = new TpmHandle(AIOTH_PERSISTED_URI_INDEX + logicalDeviceId); // Definizione dell'handle contenente l'Owner nel TPM TpmHandle ownerHandle = new TpmHandle(TpmRh.Owner); // Definizione dell'handle per la memorizzazione dell'oggetto HMAC TpmHandle hmacKeyHandle = new TpmHandle(AIOTH_PERSISTED_KEY_HANDLE + logicalDeviceId); // Definizione dell'handle della Storage Root Key, si tratta della chiave // principale utilizzata per il salvataggio di altre chiavi. Ogni chiave salvata // nel TPM infatti viene cifrata utilizzando la sua chiave "padre". // La SRK è la chiave più alta dell'albero TpmHandle srkHandle = new TpmHandle(SRK_HANDLE); UTF8Encoding utf8 = new UTF8Encoding(); // dati descrittivi dell'host e del device id byte[] nvData = utf8.GetBytes(hostName + "/" + deviceId); // chiave privata che intendiamo memorizzare nel TPM byte[] hmacKey = System.Convert.FromBase64String(encodedHmacKey); // Apertura del TPM Tpm2Device tpmDevice = new TbsDevice(); tpmDevice.Connect(); var tpm = new Tpm2(tpmDevice); // Definizione dello store Non volatile // Il primo parametro è l'Owner TPM // il terzo parametro è la funzione HMAC che intendiamo salvare // (NvPublic sta per Non volatile public area) tpm.NvDefineSpace(ownerHandle, new byte[0], new NvPublic( nvHandle, TpmAlgId.Sha256, NvAttr.Authwrite | NvAttr.Authread | NvAttr.NoDa, new byte[0], (ushort)nvData.Length)); // Scrittura nello store non volatile della funzione HMAC tpm.NvWrite(nvHandle, nvHandle, nvData, 0); // Importazione della chiave HMAC sotto la Storage Root Key TpmPublic hmacPub; CreationData creationData; byte[] creationhash; TkCreation ticket; // Passaggio della chiave privata var sensitiveCreate = new SensitiveCreate(new byte[0], hmacKey); // Definizione dell'uso che si farà della chiave var tpmPublic = new TpmPublic( TpmAlgId.Sha256, ObjectAttr.UserWithAuth | ObjectAttr.NoDA | ObjectAttr.Sign, new byte[0], new KeyedhashParms(new SchemeHmac(TpmAlgId.Sha256)), new Tpm2bDigestKeyedhash()); // Salvataggio della chiave privata nel tpm TpmPrivate hmacPrv = tpm.Create( srkHandle, sensitiveCreate, tpmPublic, new byte[0], new PcrSelection[0], out hmacPub, out creationData, out creationhash, out ticket); // Caricamento della chiave HMAC nel TPM TpmHandle loadedHmacKey = tpm.Load(srkHandle, hmacPrv, hmacPub); // Salvataggio della chiave nella memoria Non Volatile tpm.EvictControl(ownerHandle, loadedHmacKey, hmacKeyHandle); // Flush degli oggetti transienti dal tpm tpm.FlushContext(loadedHmacKey); }
public static void Main(string[] args) { try { // Keypair Generator RsaKeyPairGenerator kpGenerator = new RsaKeyPairGenerator(); kpGenerator.Init(new KeyGenerationParameters(new SecureRandom(), 1024)); // Create a keypair AsymmetricCipherKeyPair keys = kpGenerator.GenerateKeyPair(); // Connect to the TPM Tpm2Device tpmDevice = new TbsDevice(); tpmDevice.Connect(); Tpm2 tpm = new Tpm2(tpmDevice); AuthValue ownerAuth = new AuthValue(); // Create a handle based on the hash of the cert thumbprint ushort hashcode = (ushort)keys.GetHashCode(); TpmHandle nvHandle = TpmHandle.NV(hashcode); // Clean up the slot tpm[ownerAuth]._AllowErrors().NvUndefineSpace(TpmHandle.RhOwner, nvHandle); // Export serial number, the "valid from" date (the cert will be valid for 1 year, so no need to store that date, too!), the size of the keys blob and the keys themselves TextWriter textWriter = new StringWriter(); PemWriter pemWriter = new PemWriter(textWriter); pemWriter.WriteObject(keys); pemWriter.Writer.Flush(); byte[] rawData = Encoding.ASCII.GetBytes(textWriter.ToString().ToCharArray()); ushort size = (ushort)(sizeof(long) + sizeof(long) + rawData.Length + sizeof(int) + 64); ushort offset = 0; // Define a slot for the keys, which is 64 bytes bigger than we need as we write in 64-byte chunks tpm[ownerAuth].NvDefineSpace(TpmHandle.RhOwner, ownerAuth, new NvPublic(nvHandle, TpmAlgId.Sha256, NvAttr.Authread | NvAttr.Authwrite, new byte[0], size)); // Write the serial number tpm[ownerAuth].NvWrite(nvHandle, nvHandle, BitConverter.GetBytes(BigInteger.ProbablePrime(120, new Random()).LongValue), offset); offset += sizeof(long); // Write the "valid from" date (today) in FileTime format tpm[ownerAuth].NvWrite(nvHandle, nvHandle, BitConverter.GetBytes(DateTime.Today.ToFileTime()), offset); offset += sizeof(long); // Write the size of the keys tpm[ownerAuth].NvWrite(nvHandle, nvHandle, BitConverter.GetBytes(rawData.Length), offset); offset += sizeof(int); // Write the keys themselves (in 64-byte chunks) byte[] dataToWrite = new byte[64]; int index = 0; while (index < rawData.Length) { for (int i = 0; i < 64; i++) { if (index < rawData.Length) { dataToWrite[i] = rawData[index]; index++; } else { // fill the rest of the buffer with zeros dataToWrite[i] = 0; } } tpm[ownerAuth].NvWrite(nvHandle, nvHandle, dataToWrite, offset); offset += 64; } tpm.Dispose(); Console.WriteLine("Keys successfully generated and copied to TPM. Hashcode=" + hashcode.ToString()); } catch (Exception e) { Console.WriteLine("Could not generate or copy keys to TPM: " + e.Message); } }
/// <summary> /// This sample demonstrates the creation of a signing "primary" key and use of this /// key to sign data, and use of the TPM and Tpm2Lib to validate the signature. /// </summary> /// <param name="args">Arguments to this program.</param> static void Main(string[] args) { // // Parse the program arguments. If the wrong arguments are given or // are malformed, then instructions for usage are displayed and // the program terminates. // string tpmDeviceName; if (!ParseArguments(args, out tpmDeviceName)) { WriteUsage(); return; } try { // // Create the device according to the selected connection. // Tpm2Device tpmDevice; switch (tpmDeviceName) { case DeviceSimulator: tpmDevice = new TcpTpmDevice(DefaultSimulatorName, DefaultSimulatorPort); break; case DeviceWinTbs: tpmDevice = new TbsDevice(); break; default: throw new Exception("Unknown device selected."); } // // Connect to the TPM device. This function actually establishes the // connection. // tpmDevice.Connect(); // // Pass the device object used for communication to the TPM 2.0 object // which provides the command interface. // var tpm = new Tpm2(tpmDevice); if (tpmDevice is TcpTpmDevice) { // // If we are using the simulator, we have to do a few things the // firmware would usually do. These actions have to occur after // the connection has been established. // tpmDevice.PowerCycle(); tpm.Startup(Su.Clear); } // // 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(); // // The TPM needs a template that describes the parameters of the key // or other object to be created. The template below instructs the TPM // to create a new 2048-bit non-migratable signing key. // var keyTemplate = new TpmPublic(TpmAlgId.Sha1, // Name algorithm ObjectAttr.UserWithAuth | ObjectAttr.Sign | // Signing key ObjectAttr.FixedParent | ObjectAttr.FixedTPM | // Non-migratable ObjectAttr.SensitiveDataOrigin, new byte[0], // No policy new RsaParms(new SymDefObject(), new SchemeRsassa(TpmAlgId.Sha1), 2048, 0), new Tpm2bPublicKeyRsa()); // // Authorization for the key we are about to create. // var keyAuth = new byte[] { 1, 2, 3 }; TpmPublic keyPublic; CreationData creationData; TkCreation creationTicket; byte[] creationHash; // // Ask the TPM to create a new primary RSA signing key. // TpmHandle keyHandle = tpm[ownerAuth].CreatePrimary( TpmHandle.RhOwner, // In the owner-hierarchy new SensitiveCreate(keyAuth, new byte[0]), // With this auth-value keyTemplate, // Describes key new byte[0], // For creation ticket new PcrSelection[0], // For creation ticket out keyPublic, // Out pubKey and attributes out creationData, out creationHash, // Not used here out creationTicket); // // Print out text-versions of the public key just created // Console.WriteLine("New public key\n" + keyPublic.ToString()); // // Use the key to sign some data // byte[] message = Encoding.Unicode.GetBytes("ABC"); TpmHash dataToSign = TpmHash.FromData(TpmAlgId.Sha1, message); // // A different structure is returned for each signing scheme, // so cast the interface to our signature type (see third argument). // // As an alternative, 'signature' can be of type ISignatureUnion and // cast to SignatureRssa whenever a signature specific type is needed. // var signature = tpm[keyAuth].Sign(keyHandle, // Handle of signing key dataToSign.HashData, // Data to sign new SchemeRsassa(TpmAlgId.Sha1), // Default scheme TpmHashCheck.NullHashCheck()) as SignatureRsassa; // // Print the signature. // Console.WriteLine("Signature: " + BitConverter.ToString(signature.sig)); // // Use the TPM library to validate the signature // bool sigOk = keyPublic.VerifySignatureOverData(message, signature); if (!sigOk) { throw new Exception("Signature did not validate."); } Console.WriteLine("Verified signature with TPM2lib (software implementation)."); // // Load the public key into another slot in the TPM and then // use the TPM to validate the signature // TpmHandle pubHandle = tpm.LoadExternal(null, keyPublic, TpmHandle.RhOwner); tpm.VerifySignature(pubHandle, dataToSign.HashData, signature); Console.WriteLine("Verified signature with TPM."); // // The default behavior of Tpm2Lib is to create an exception if the // signature does not validate. If an error is expected the library can // be notified of this, or the exception can be turned into a value that // can be later queried. The following are examples of this. // signature.sig[0] ^= 1; tpm._ExpectError(TpmRc.Signature).VerifySignature(pubHandle, dataToSign.HashData, signature); tpm._AllowErrors().VerifySignature(pubHandle, dataToSign.HashData, signature); if (tpm._GetLastResponseCode() != TpmRc.Signature) { throw new Exception("TPM returned unexpected return code."); } Console.WriteLine("Verified that invalid signature causes TPM_RC_SIGNATURE return code."); // // Clean up of used handles. // tpm.FlushContext(keyHandle); tpm.FlushContext(pubHandle); // // (Note that serialization is not supported on WinRT) // // Demonstrate the use of XML persistence by saving keyPublic to // a file and making a copy by reading it back into a new object // // NOTE: 12-JAN-2016: May be removing support for policy // serialization. We'd like to get feedback on whether // this is a desirable feature and should be retained. // // { // const string fileName = "sample.xml"; // string xmlVersionOfObject = keyPublic.GetXml(); // keyPublic.XmlSerializeToFile(fileName); // var copyOfPublic = TpmStructureBase.XmlDeserializeFromFile<TpmPublic>(fileName); // // // // // Demonstrate Tpm2Lib support of TPM-structure equality operators // // // if (copyOfPublic != keyPublic) // { // Console.WriteLine("Library bug persisting data."); // } // } // // // Clean up. // tpm.Dispose(); } catch (Exception e) { Console.WriteLine("Exception occurred: {0}", e.Message); } Console.WriteLine("Press Any Key to continue."); Console.ReadLine(); }
private void RetrieveTpmProperties() { WriteConsoleVerbose("Retrieving TPM properties ..."); using (var tpmDevice = new TbsDevice()) { WriteConsoleDebug("Connecting to TPM ..."); tpmDevice.Connect(); using (var tpm = new Tpm2(tpmDevice)) { // ReSharper disable JoinDeclarationAndInitializer uint tpmProperty; TaggedTpmPropertyArray tpmProperties; // ReSharper enable JoinDeclarationAndInitializer WriteConsoleDebug("Retrieving TPM capability: TPM_PROPERTIES (Property: PT_FIXED)"); tpm.GetCapability(Cap.TpmProperties, (uint)Pt.PtFixed, 1000, out var capPropertiesFixed); tpmProperties = (TaggedTpmPropertyArray)capPropertiesFixed; #region Manufacturer ManufacturerId = tpmProperties.tpmProperty[Pt.Manufacturer - Pt.PtFixed].value; var tpmManufacturerBytes = BitConverter.GetBytes(ManufacturerId); Array.Reverse(tpmManufacturerBytes); // Assumes little-endian var tpmManufacturerName = new char[tpmManufacturerBytes.Length]; for (var index = 0; index < tpmManufacturerName.Length; index++) { // Unprintable character or invalid 7-bit ASCII if (tpmManufacturerBytes[index] < 32 || tpmManufacturerBytes[index] > 126) { break; } tpmManufacturerName[index] = Convert.ToChar(tpmManufacturerBytes[index]); } ManufacturerName = new string(tpmManufacturerName).Trim(); ManufacturerModel = tpmProperties.tpmProperty[Pt.VendorTpmType - Pt.PtFixed].value; #endregion #region Specification tpmProperty = tpmProperties.tpmProperty[Pt.FamilyIndicator - Pt.PtFixed].value; var tpmFamilyIndicator = BitConverter.GetBytes(tpmProperty); Array.Reverse(tpmFamilyIndicator); // Assumes little-endian SpecificationVersion = Encoding.ASCII.GetString(tpmFamilyIndicator).Trim('\0'); SpecificationLevel = tpmProperties.tpmProperty[Pt.Level - Pt.PtFixed].value; tpmProperty = tpmProperties.tpmProperty[Pt.Revision - Pt.PtFixed].value; SpecificationRevision = (float)tpmProperty / 100; tpmProperty = tpmProperties.tpmProperty[Pt.Year - Pt.PtFixed].value; SpecificationDate = new DateTime((int)tpmProperty - 1, 12, 31); tpmProperty = tpmProperties.tpmProperty[Pt.DayOfYear - Pt.PtFixed].value; SpecificationDate = SpecificationDate.AddDays(tpmProperty); #endregion #region Platform-specific tpmProperty = tpmProperties.tpmProperty[Pt.PsFamilyIndicator - Pt.PtFixed].value; PlatformSpecificFamily = ((Ps)tpmProperty).ToString(); PlatformSpecificationLevel = tpmProperties.tpmProperty[Pt.PsLevel - Pt.PtFixed].value; tpmProperty = tpmProperties.tpmProperty[Pt.PsRevision - Pt.PtFixed].value; PlatformSpecificationRevision = (float)tpmProperty / 100; tpmProperty = tpmProperties.tpmProperty[Pt.PsYear - Pt.PtFixed].value; PlatformSpecificationDate = new DateTime((int)tpmProperty - 1, 12, 31); tpmProperty = tpmProperties.tpmProperty[Pt.PsDayOfYear - Pt.PtFixed].value; PlatformSpecificationDate = SpecificationDate.AddDays(tpmProperty); #endregion #region Firmware var tpmFirmwareVersion = new uint[2]; tpmFirmwareVersion[0] = tpmProperties.tpmProperty[Pt.FirmwareVersion1 - Pt.PtFixed].value; tpmFirmwareVersion[1] = tpmProperties.tpmProperty[Pt.FirmwareVersion2 - Pt.PtFixed].value; FirmwareVersion = new Version((int)(tpmFirmwareVersion[0] >> 16), (int)(tpmFirmwareVersion[0] & 0xFFFF), (int)tpmFirmwareVersion[1] >> 16, (int)tpmFirmwareVersion[1] & 0xFFFF); #endregion #region Characteristics tpmProperty = tpmProperties.tpmProperty[Pt.Memory - Pt.PtFixed].value; var tpmMemory = (MemoryAttr)tpmProperty; MemoryManagement = tpmMemory.ToString(); tpmProperty = tpmProperties.tpmProperty[Pt.Modes - Pt.PtFixed].value; var tpmModes = (ModesAttr)tpmProperty; SupportedModes = tpmModes.ToString(); #endregion WriteConsoleDebug("Retrieving TPM capability: TPM_PROPERTIES (Property: PT_VAR)"); tpm.GetCapability(Cap.TpmProperties, (uint)Pt.PtVar, 1000, out var capPropertiesVar); tpmProperties = (TaggedTpmPropertyArray)capPropertiesVar; #region Configuration tpmProperty = tpmProperties.tpmProperty[Pt.Permanent - Pt.PtVar].value; var tpmPermanent = (PermanentAttr)tpmProperty; PermanentAttributes = tpmPermanent.ToString(); tpmProperty = tpmProperties.tpmProperty[Pt.StartupClear - Pt.PtVar].value; var tpmStartupClear = (StartupClearAttr)tpmProperty; StartupAttributes = tpmStartupClear.ToString(); #endregion } } }
/// <summary> /// This sample demonstrates the creation of a signing "primary" key and use of this /// key to sign data, and use of the TPM and TSS.Net to validate the signature. /// </summary> /// <param name="args">Arguments to this program.</param> static void Main(string[] args) { // // Parse the program arguments. If the wrong arguments are given or // are malformed, then instructions for usage are displayed and // the program terminates. // string tpmDeviceName; if (!ParseArguments(args, out tpmDeviceName)) { WriteUsage(); return; } try { // // Create the device according to the selected connection. // Tpm2Device tpmDevice; switch (tpmDeviceName) { case DeviceSimulator: tpmDevice = new TcpTpmDevice(DefaultSimulatorName, DefaultSimulatorPort); break; case DeviceWinTbs: tpmDevice = new TbsDevice(); break; default: throw new Exception("Unknown device selected."); } // // Connect to the TPM device. This function actually establishes the // connection. // tpmDevice.Connect(); // // Pass the device object used for communication to the TPM 2.0 object // which provides the command interface. // var tpm = new Tpm2(tpmDevice); if (tpmDevice is TcpTpmDevice) { // // If we are using the simulator, we have to do a few things the // firmware would usually do. These actions have to occur after // the connection has been established. // tpmDevice.PowerCycle(); tpm.Startup(Su.Clear); } // // 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(); // // The TPM needs a template that describes the parameters of the key // or other object to be created. The template below instructs the TPM // to create a new 2048-bit non-migratable signing key. // var keyTemplate = new TpmPublic(TpmAlgId.Sha1, // Name algorithm ObjectAttr.UserWithAuth | ObjectAttr.Sign | // Signing key ObjectAttr.FixedParent | ObjectAttr.FixedTPM | // Non-migratable ObjectAttr.SensitiveDataOrigin, null, // No policy new RsaParms(new SymDefObject(), new SchemeRsassa(TpmAlgId.Sha1), 2048, 0), new Tpm2bPublicKeyRsa()); // // Authorization for the key we are about to create. // var keyAuth = new byte[] { 1, 2, 3 }; TpmPublic keyPublic; CreationData creationData; TkCreation creationTicket; byte[] creationHash; // // Ask the TPM to create a new primary RSA signing key. // TpmHandle keyHandle = tpm[ownerAuth].CreatePrimary( TpmRh.Owner, // In the owner-hierarchy new SensitiveCreate(keyAuth, null), // With this auth-value keyTemplate, // Describes key null, // Extra data for creation ticket new PcrSelection[0], // Non-PCR-bound out keyPublic, // PubKey and attributes out creationData, out creationHash, out creationTicket); // Not used here // // Print out text-versions of the public key just created // Console.WriteLine("New public key\n" + keyPublic.ToString()); // // Use the key to sign some data // byte[] message = Encoding.Unicode.GetBytes("ABC"); TpmHash digestToSign = TpmHash.FromData(TpmAlgId.Sha1, message); // // A different structure is returned for each signing scheme, // so cast the interface to our signature type (see third argument). // // As an alternative, 'signature' can be of type ISignatureUnion and // cast to SignatureRssa whenever a signature specific type is needed. // var signature = tpm[keyAuth].Sign(keyHandle, // Handle of signing key digestToSign, // Data to sign null, // Use key's scheme TpmHashCheck.Null()) as SignatureRsassa; // // Print the signature. // Console.WriteLine("Signature: " + BitConverter.ToString(signature.sig)); // // Use the TPM library to validate the signature // bool sigOk = keyPublic.VerifySignatureOverData(message, signature); if (!sigOk) { throw new Exception("Signature did not validate."); } Console.WriteLine("Verified signature with TPM2lib (software implementation)."); // // Load the public key into another slot in the TPM and then // use the TPM to validate the signature // TpmHandle pubHandle = tpm.LoadExternal(null, keyPublic, TpmRh.Owner); tpm.VerifySignature(pubHandle, digestToSign, signature); Console.WriteLine("Verified signature with TPM."); // // The default behavior of Tpm2Lib is to create an exception if the // signature does not validate. If an error is expected the library can // be notified of this, or the exception can be turned into a value that // can be later queried. The following are examples of this. // signature.sig[0] ^= 1; tpm._ExpectError(TpmRc.Signature) .VerifySignature(pubHandle, digestToSign, signature); if (tpm._GetLastResponseCode() != TpmRc.Signature) { throw new Exception("TPM returned unexpected return code."); } Console.WriteLine("Verified that invalid signature causes TPM_RC_SIGNATURE return code."); // // Clean up of used handles. // tpm.FlushContext(keyHandle); tpm.FlushContext(pubHandle); // // (Note that serialization is not supported on WinRT) // // Demonstrate the use of XML persistence by saving keyPublic to // a file and making a copy by reading it back into a new object // // NOTE: 12-JAN-2016: May be removing support for policy // serialization. We'd like to get feedback on whether // this is a desirable feature and should be retained. // // { // const string fileName = "sample.xml"; // string xmlVersionOfObject = keyPublic.GetXml(); // keyPublic.XmlSerializeToFile(fileName); // var copyOfPublic = TpmStructureBase.XmlDeserializeFromFile<TpmPublic>(fileName); // // // // // Demonstrate Tpm2Lib support of TPM-structure equality operators // // // if (copyOfPublic != keyPublic) // { // Console.WriteLine("Library bug persisting data."); // } // } // // // Clean up. // tpm.Dispose(); } catch (Exception e) { Console.WriteLine("Exception occurred: {0}", e.Message); } Console.WriteLine("Press Any Key to continue."); Console.ReadLine(); }
public Byte[] SignHmac(Byte[] dataToSign) { TpmHandle hmacKeyHandle = new TpmHandle(AIOTH_PERSISTED_KEY_HANDLE + logicalDeviceId); int dataIndex = 0; Byte[] iterationBuffer; Byte[] hmac = { }; if (dataToSign.Length <= 1024) { try { // Open the TPM Tpm2Device tpmDevice = new TbsDevice(); tpmDevice.Connect(); var tpm = new Tpm2(tpmDevice); // Calculate the HMAC in one shot hmac = tpm.Hmac(hmacKeyHandle, dataToSign, TpmAlgId.Sha256); // Dispose of the TPM tpm.Dispose(); } catch { return hmac; } } else { try { // Open the TPM Tpm2Device tpmDevice = new TbsDevice(); tpmDevice.Connect(); var tpm = new Tpm2(tpmDevice); // Start the HMAC sequence Byte[] hmacAuth = new byte[0]; TpmHandle hmacHandle = tpm.HmacStart(hmacKeyHandle, hmacAuth, TpmAlgId.Sha256); while (dataToSign.Length > dataIndex + 1024) { // Repeat to update the hmac until we only hace <=1024 bytes left iterationBuffer = new Byte[1024]; Array.Copy(dataToSign, dataIndex, iterationBuffer, 0, 1024); tpm.SequenceUpdate(hmacHandle, iterationBuffer); dataIndex += 1024; } // Finalize the hmac with the remainder of the data iterationBuffer = new Byte[dataToSign.Length - dataIndex]; Array.Copy(dataToSign, dataIndex, iterationBuffer, 0, dataToSign.Length - dataIndex); TkHashcheck nullChk; hmac = tpm.SequenceComplete(hmacHandle, iterationBuffer, TpmHandle.RhNull, out nullChk); // Dispose of the TPM tpm.Dispose(); } catch { return hmac; } } return hmac; }
/// <summary> /// Executes the GetCapabilities functionality. After parsing arguments, the /// function connects to the selected TPM device and invokes the GetCapabilities /// command on that connection. If the command was successful, the retrieved /// capabilities are displayed. /// </summary> /// <param name="args">Arguments to this program.</param> static void Main(string[] args) { // // Parse the program arguments. If the wrong arguments are given or // are malformed, then instructions for usage are displayed and // the program terminates. // string tpmDeviceName; if (!ParseArguments(args, out tpmDeviceName)) { WriteUsage(); return; } try { // // Create the device according to the selected connection. // Tpm2Device tpmDevice; switch (tpmDeviceName) { case DeviceSimulator: tpmDevice = new TcpTpmDevice(DefaultSimulatorName, DefaultSimulatorPort); break; case DeviceWinTbs: tpmDevice = new TbsDevice(); break; default: throw new Exception("Unknown device selected."); } // // Connect to the TPM device. This function actually establishes the // connection. // tpmDevice.Connect(); // // Pass the device object used for communication to the TPM 2.0 object // which provides the command interface. // var tpm = new Tpm2(tpmDevice); if (tpmDevice is TcpTpmDevice) { // // If we are using the simulator, we have to do a few things the // firmware would usually do. These actions have to occur after // the connection has been established. // tpmDevice.PowerCycle(); tpm.Startup(Su.Clear); } // // Query different capabilities // ICapabilitiesUnion caps; tpm.GetCapability(Cap.Algs, 0, 1000, out caps); var algsx = (AlgPropertyArray)caps; Console.WriteLine("Supported algorithms:"); foreach (var alg in algsx.algProperties) { Console.WriteLine(" {0}", alg.alg.ToString()); } Console.WriteLine("Supported commands:"); tpm.GetCapability(Cap.TpmProperties, (uint)Pt.TotalCommands, 1, out caps); tpm.GetCapability(Cap.Commands, (uint)TpmCc.First + 1, TpmCc.Last - TpmCc.First + 1, out caps); var commands = (CcaArray)caps; List<TpmCc> implementedCc = new List<TpmCc>(); foreach (var attr in commands.commandAttributes) { var commandCode = (TpmCc)((uint)attr & 0x0000FFFFU); // // Filter placehoder(s) // if(commandCode == TpmCc.None) { continue; } 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) && // // Fiter placeholder(s) // ((TpmCc)cc != TpmCc.None) && ((TpmCc)cc != TpmCc.First) && ((TpmCc)cc != TpmCc.Last) ) { Console.WriteLine(" {0}", cc.ToString()); } } // // As an alternative: call GetCapabilities more than once to obtain all values // byte more; var firstCommandCode = (uint)TpmCc.None; do { more = tpm.GetCapability(Cap.Commands, firstCommandCode, 10, out caps); commands = (CcaArray)caps; // // Commands are sorted; getting the last element as it will be the largest. // uint lastCommandCode = (uint)commands.commandAttributes[commands.commandAttributes.Length - 1] & 0x0000FFFFU; firstCommandCode = lastCommandCode; } while (more == 1); // // Read PCR attributes. Cap.Pcrs returns the list of PCRs which are supported // in different PCR banks. The PCR banks are identified by the hash algorithm // used to extend values into the PCRs of this bank. // tpm.GetCapability(Cap.Pcrs, 0, 255, out caps); PcrSelection[] pcrs = ((PcrSelectionArray)caps).pcrSelections; Console.WriteLine(); Console.WriteLine("Available PCR banks:"); foreach (PcrSelection pcrBank in pcrs) { var sb = new StringBuilder(); sb.AppendFormat("PCR bank for algorithm {0} has registers at index:", pcrBank.hash); sb.AppendLine(); foreach (uint selectedPcr in pcrBank.GetSelectedPcrs()) { sb.AppendFormat("{0},", selectedPcr); } Console.WriteLine(sb); } // // Read PCR attributes. Cap.PcrProperties checks for certain properties of each PCR register. // tpm.GetCapability(Cap.PcrProperties, 0, 255, out caps); Console.WriteLine(); Console.WriteLine("PCR attributes:"); TaggedPcrSelect[] pcrProperties = ((TaggedPcrPropertyArray)caps).pcrProperty; foreach (TaggedPcrSelect pcrProperty in pcrProperties) { if ((PtPcr)pcrProperty.tag == PtPcr.None) { continue; } uint pcrIndex = 0; var sb = new StringBuilder(); sb.AppendFormat("PCR property {0} supported by these registers: ", (PtPcr)pcrProperty.tag); sb.AppendLine(); foreach (byte pcrBitmap in pcrProperty.pcrSelect) { for (int i = 0; i < 8; i++) { if ((pcrBitmap & (1 << i)) != 0) { sb.AppendFormat("{0},", pcrIndex); } pcrIndex++; } } Console.WriteLine(sb); } // // Clean up. // tpm.Dispose(); } catch (Exception e) { Console.WriteLine("Exception occurred: {0}", e.Message); } Console.WriteLine("Press Any Key to continue."); Console.ReadLine(); }
/// <summary> /// Executes the hashing functionality. After parsing arguments, the /// function connects to the selected TPM device and invokes the TPM /// commands on that connection. /// </summary> /// <param name="args">Arguments to this program.</param> static void Main(string[] args) { // // Parse the program arguments. If the wrong arguments are given or // are malformed, then instructions for usage are displayed and // the program terminates. // string tpmDeviceName; if (!ParseArguments(args, out tpmDeviceName)) { WriteUsage(); return; } try { // // Create the device according to the selected connection. // Tpm2Device tpmDevice; switch (tpmDeviceName) { case DeviceSimulator: tpmDevice = new TcpTpmDevice(DefaultSimulatorName, DefaultSimulatorPort); break; case DeviceWinTbs: tpmDevice = new TbsDevice(); break; default: throw new Exception("Unknown device selected."); } // // Connect to the TPM device. This function actually establishes the // connection. // tpmDevice.Connect(); // // Pass the device object used for communication to the TPM 2.0 object // which provides the command interface. // var tpm = new Tpm2(tpmDevice); if (tpmDevice is TcpTpmDevice) { // // If we are using the simulator, we have to do a few things the // firmware would usually do. These actions have to occur after // the connection has been established. // tpmDevice.PowerCycle(); tpm.Startup(Su.Clear); } NVReadWrite(tpm); NVCounter(tpm); // // Clean up. // tpm.Dispose(); } catch (Exception e) { Console.WriteLine("Exception occurred: {0}", e.Message); } Console.WriteLine("Press Any Key to continue."); Console.ReadLine(); }
/// <summary> /// This sample demonstrates the creation of a signing "primary" key and use of this /// key to sign data, and use of the TPM and Tpm2Lib to validate the signature. /// </summary> /// <param name="args">Arguments to this program.</param> static void Main(string[] args) { string tpmDeviceName; // // Parse the program arguments. If the wrong arguments are given or // are malformed, then instructions for usage are displayed and // the program terminates. // if (!ParseArguments(args, out tpmDeviceName)) { WriteUsage(); return; } try { // // Create the device according to the selected connection. // Tpm2Device tpmDevice; switch (tpmDeviceName) { case DeviceSimulator: tpmDevice = new TcpTpmDevice(DefaultSimulatorName, DefaultSimulatorPort); break; case DeviceWinTbs: tpmDevice = new TbsDevice(); break; default: throw new Exception("Unknown device selected."); } // // Connect to the TPM device. This function actually establishes the connection. // tpmDevice.Connect(); // // Pass the device object used for communication to the TPM 2.0 object // which provides the command interface. // var tpm = new Tpm2(tpmDevice); if (tpmDevice is TcpTpmDevice) { // // If we are using the simulator, we have to do a few things the // firmware would usually do. These actions have to occur after // the connection has been established. // tpmDevice.PowerCycle(); tpm.Startup(Su.Clear); } // // Run individual tests. // SimplePolicy(tpm); PolicyOr(tpm); PolicySerialization(); PolicyEvaluationWithCallback(tpm); PolicyEvaluationWithCallback2(tpm); // // Clean up. // tpm.Dispose(); } catch (TpmException e) { // // If a command fails because an unexpected return code is in the response, // i.e., TPM returns an error code where success is expected or success // where an error code is expected. Or if the response is malformed, then // the unmarshaling code will throw a TPM exception. // The Error string will contain a description of the return code. Usually the // return code will be a known TPM return code. However, if using the TPM through // TBS, TBS might encode internal error codes into the response code. For instance // a return code of 0x80280400 indicates that a command is blocked by TBS. This // error code is also returned if the command is not implemented by the TPM. // // You can see the information included in the TPM exception by removing the // checks for available TPM commands above and running the sample on a TPM // without the required commands. // Console.WriteLine("TPM exception occurred: {0}", e.ErrorString); Console.WriteLine("Call stack: {0}", e.StackTrace); } catch (Exception e) { Console.WriteLine("Exception occurred: {0}", e.Message); } Console.WriteLine("Press Any Key to continue."); Console.ReadLine(); }
/// <summary> /// Executes the hashing functionality. After parsing arguments, the /// function connects to the selected TPM device and invokes the TPM /// commands on that connection. /// </summary> /// <param name="args">Arguments to this program.</param> static void Main(string[] args) { // // Parse the program arguments. If the wrong arguments are given or // are malformed, then instructions for usage are displayed and // the program terminates. // string tpmDeviceName; if (!ParseArguments(args, out tpmDeviceName)) { WriteUsage(); return; } try { // // Create the device according to the selected connection. // Tpm2Device tpmDevice; switch (tpmDeviceName) { case DeviceSimulator: tpmDevice = new TcpTpmDevice(DefaultSimulatorName, DefaultSimulatorPort); break; case DeviceWinTbs: tpmDevice = new TbsDevice(); break; default: throw new Exception("Unknown device selected."); } // // Connect to the TPM device. This function actually establishes the // connection. // tpmDevice.Connect(); // // Pass the device object used for communication to the TPM 2.0 object // which provides the command interface. // var tpm = new Tpm2(tpmDevice); if (tpmDevice is TcpTpmDevice) { // // If we are using the simulator, we have to do a few things the // firmware would usually do. These actions have to occur after // the connection has been established. // tpmDevice.PowerCycle(); tpm.Startup(Su.Clear); } Pcrs(tpm); QuotePcrs(tpm); StorageRootKey(tpm); // // Need a synchronization event to avoid disposing TPM object before // asynchronous method completed. // var sync = new AutoResetEvent(false); Console.WriteLine("Calling asynchronous method."); PrimarySigningKeyAsync(tpm, sync); Console.WriteLine("Waiting for asynchronous method to complete."); sync.WaitOne(); // // Clean up. // tpm.Dispose(); } catch (Exception e) { Console.WriteLine("Exception occurred: {0}", e.Message); } Console.WriteLine("Press Any Key to continue."); Console.ReadLine(); }
/// <summary> /// Executes the GetCapabilities functionality. After parsing arguments, the /// function connects to the selected TPM device and invokes the GetCapabilities /// command on that connection. If the command was successful, the retrieved /// capabilities are displayed. /// </summary> /// <param name="args">Arguments to this program.</param> static void Main(string[] args) { // // Parse the program arguments. If the wrong arguments are given or // are malformed, then instructions for usage are displayed and // the program terminates. // string tpmDeviceName; if (!ParseArguments(args, out tpmDeviceName)) { WriteUsage(); return; } try { // // Create the device according to the selected connection. // Tpm2Device tpmDevice; switch (tpmDeviceName) { case DeviceSimulator: tpmDevice = new TcpTpmDevice(DefaultSimulatorName, DefaultSimulatorPort); break; case DeviceWinTbs: tpmDevice = new TbsDevice(); break; default: throw new Exception("Unknown device selected."); } // // Connect to the TPM device. This function actually establishes the // connection. // tpmDevice.Connect(); // // Pass the device object used for communication to the TPM 2.0 object // which provides the command interface. // var tpm = new Tpm2(tpmDevice); if (tpmDevice is TcpTpmDevice) { // // If we are using the simulator, we have to do a few things the // firmware would usually do. These actions have to occur after // the connection has been established. // tpmDevice.PowerCycle(); tpm.Startup(Su.Clear); } // // Query different capabilities // ICapabilitiesUnion caps; tpm.GetCapability(Cap.Algs, 0, 1000, out caps); var algsx = (AlgPropertyArray)caps; Console.WriteLine("Supported algorithms:"); foreach (var alg in algsx.algProperties) { Console.WriteLine(" {0}", alg.alg.ToString()); } Console.WriteLine("Supported commands:"); tpm.GetCapability(Cap.TpmProperties, (uint)Pt.TotalCommands, 1, out caps); tpm.GetCapability(Cap.Commands, (uint)TpmCc.First + 1, TpmCc.Last - TpmCc.First + 1, out caps); var commands = (CcaArray)caps; List <TpmCc> implementedCc = new List <TpmCc>(); foreach (var attr in commands.commandAttributes) { var commandCode = (TpmCc)((uint)attr & 0x0000FFFFU); // // Filter placehoder(s) // if (commandCode == TpmCc.None) { continue; } 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) && // // Fiter placeholder(s) // ((TpmCc)cc != TpmCc.None) && ((TpmCc)cc != TpmCc.First) && ((TpmCc)cc != TpmCc.Last)) { Console.WriteLine(" {0}", cc.ToString()); } } // // As an alternative: call GetCapabilities more than once to obtain all values // byte more; var firstCommandCode = (uint)TpmCc.None; do { more = tpm.GetCapability(Cap.Commands, firstCommandCode, 10, out caps); commands = (CcaArray)caps; // // Commands are sorted; getting the last element as it will be the largest. // uint lastCommandCode = (uint)commands.commandAttributes[commands.commandAttributes.Length - 1] & 0x0000FFFFU; firstCommandCode = lastCommandCode; } while (more == 1); // // Read PCR attributes. Cap.Pcrs returns the list of PCRs which are supported // in different PCR banks. The PCR banks are identified by the hash algorithm // used to extend values into the PCRs of this bank. // tpm.GetCapability(Cap.Pcrs, 0, 255, out caps); PcrSelection[] pcrs = ((PcrSelectionArray)caps).pcrSelections; Console.WriteLine(); Console.WriteLine("Available PCR banks:"); foreach (PcrSelection pcrBank in pcrs) { var sb = new StringBuilder(); sb.AppendFormat("PCR bank for algorithm {0} has registers at index:", pcrBank.hash); sb.AppendLine(); foreach (uint selectedPcr in pcrBank.GetSelectedPcrs()) { sb.AppendFormat("{0},", selectedPcr); } Console.WriteLine(sb); } // // Read PCR attributes. Cap.PcrProperties checks for certain properties of each PCR register. // tpm.GetCapability(Cap.PcrProperties, 0, 255, out caps); Console.WriteLine(); Console.WriteLine("PCR attributes:"); TaggedPcrSelect[] pcrProperties = ((TaggedPcrPropertyArray)caps).pcrProperty; foreach (TaggedPcrSelect pcrProperty in pcrProperties) { if ((PtPcr)pcrProperty.tag == PtPcr.None) { continue; } uint pcrIndex = 0; var sb = new StringBuilder(); sb.AppendFormat("PCR property {0} supported by these registers: ", (PtPcr)pcrProperty.tag); sb.AppendLine(); foreach (byte pcrBitmap in pcrProperty.pcrSelect) { for (int i = 0; i < 8; i++) { if ((pcrBitmap & (1 << i)) != 0) { sb.AppendFormat("{0},", pcrIndex); } pcrIndex++; } } Console.WriteLine(sb); } // // Clean up. // tpm.Dispose(); } catch (Exception e) { Console.WriteLine("Exception occurred: {0}", e.Message); } Console.WriteLine("Press Any Key to continue."); Console.ReadLine(); }
/// <summary> /// Executes the GetRandom functionality. After parsing arguments, the function /// connects to the selected TPM device and invokes the GetRandom command on /// that connection. If the command was successful, the random byte stream /// is displayed. /// </summary> /// <param name="args">Arguments to this program.</param> static void Main(string[] args) { // // Parse the program arguments. If the wrong arguments are given or // are malformed, then instructions for usage are displayed and // the program terminates. // string tpmDeviceName; ushort bytesRequested; if (!ParseArguments(args, out tpmDeviceName, out bytesRequested)) { WriteUsage(); return; } try { // // Create the device according to the selected connection. // Tpm2Device tpmDevice; switch (tpmDeviceName) { case DeviceSimulator: tpmDevice = new TcpTpmDevice(DefaultSimulatorName, DefaultSimulatorPort); break; case DeviceWinTbs: tpmDevice = new TbsDevice(); break; default: throw new Exception("Unknown device selected."); } // // Connect to the TPM device. This function actually establishes the // connection. // tpmDevice.Connect(); // // Pass the device object used for communication to the TPM 2.0 object // which provides the command interface. // var tpm = new Tpm2(tpmDevice); if (tpmDevice is TcpTpmDevice) { // // If we are using the simulator, we have to do a few things the // firmware would usually do. These actions have to occur after // the connection has been established. // tpmDevice.PowerCycle(); tpm.Startup(Su.Clear); } // // Execute the TPM2_GetRandom command. The function takes the requested // number of bytes as input and returns the random bytes generated by // the TPM. // byte[] randomBytes = tpm.GetRandom(bytesRequested); // // Output the generated random byte string to the console. // WriteBytes(randomBytes); // // Clean up. // tpm.Dispose(); } catch (Exception e) { Console.WriteLine("Exception occurred: {0}", e.Message); } Console.WriteLine("Press Any Key to continue."); Console.ReadLine(); }