Example #1
0
    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);
        }
    }
Example #2
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);
                }
            }
        }
Example #3
0
        } //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;
        }
Example #5
0
        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();
        }
Example #6
0
        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);
        }
Example #7
0
        /// <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);
        }
Example #8
0
 public static void PowerCycle(Tpm2 tpm, Su shutdownMode, Su startupMode)
 {
     tpm._AllowErrors()
     .Shutdown(shutdownMode);
     tpm._GetUnderlyingDevice().PowerCycle();
     tpm.Startup(startupMode);
 }
Example #9
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);
    }
Example #10
0
        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
            }
        }
Example #12
0
        } // 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));
        }
Example #13
0
        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);
        }
Example #14
0
        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
Example #15
0
        } // 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
Example #16
0
        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
Example #17
0
        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);
        }
Example #18
0
        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);
            }
        }
Example #19
0
    /// <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);
    }
Example #20
0
        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
Example #21
0
        /// <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);
        }
Example #22
0
        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);
        }
Example #23
0
        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
Example #24
0
        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);
        }
Example #25
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();
        }
Example #27
0
        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);
        }
Example #28
0
        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);
        }
Example #29
0
 public override void Open(string location)
 {
     lock (m_lock)
     {
         base.Open(location);
         m_tpmDevice.Connect();
         m_tpm = new Tpm2(m_tpmDevice);
     }
 }
Example #30
0
        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);
        }