Tpm2 provides methods to create TPM-compatible byte streams and unmarshal responses. It is used in conjunction with a TPM device (implementing Tpm2Device) that communicates with the actual TPM device. TPM commands map 1:1 to corresponding methods in Tpm2 (with parameter translations described elsewhere). Tpm2 also provides a few commands that are tagged with Ex (like Tpm2.StartAuthSessionEx). These commands provide a slightly higher level of abstraction when using the underlying native TPM command is tricky or verbose. Tpm2 also provides a few commands that are preceded by _ like _AllowErrors(). These commands are not sent to the TPM, but instead change the behavior of later TPM commands (often for the next command invocation only). Finally, Tpm2.Instrumentation provides access to TPM debug functionality (will not be available on release/production TPMs.)
Inheritance: IDisposable
Example #1
0
        internal override TpmRc Execute(Tpm2 tpm, AuthSession sess, PolicyTree policy)
        {
            byte includeName = IncludeObjectNameInPolicyHash ? (byte)1 : (byte)0;

            tpm.PolicyDuplicationSelect(sess, DupObjectName, NewParentName, includeName);
            return(tpm._GetLastResponseCode());
        }
Example #2
0
        internal override TpmRc Execute(Tpm2 tpm, AuthSession sess, PolicyTree policy)
        {
            TpmRc res;

            if (AuthorizationHandle == null)
            {
                TpmHandle   nvHandle, authHandle;
                SessionBase nvAuth;
                AssociatedPolicy.ExecutePolicyNvCallback(this, out authHandle,
                                                         out nvHandle, out nvAuth);
                tpm[nvAuth].PolicyNV(authHandle, nvHandle, sess,
                                     OperandB, Offset, Operation);
                res = tpm._GetLastResponseCode();

                if (!(nvAuth is Pwap))
                {
                    tpm.FlushContext(nvAuth);
                }
            }
            else
            {
                tpm[NvAccessAuth].PolicyNV(AuthorizationHandle, NvIndex, sess,
                                           OperandB, Offset, Operation);
                res = tpm._GetLastResponseCode();
            }
            return(res);
        }
Example #3
0
        internal override TpmRc Execute(Tpm2 tpm, AuthSession sess, PolicyTree policy)
        {
            byte writtenName = IsNvIndexRequiredToHaveBeenWritten ? (byte)1 : (byte)0;

            tpm.PolicyNvWritten(sess, writtenName);
            return(tpm._GetLastResponseCode());
        }
Example #4
0
 internal override TpmRc Execute(Tpm2 tpm, AuthSession sess, PolicyTree policy)
 {
     tpm.PolicyPassword(sess);
     sess.SessIncludesAuth = true;
     sess.PlaintextAuth    = true;
     return(tpm._GetLastResponseCode());
 }
Example #5
0
        private TpmHandle[] GetAllLoadedEntities(Tpm2 tpm)
        {
            var handles = new List <TpmHandle>();

            handles.AddRange(GetLoadedEntities(tpm, Ht.Transient));
            handles.AddRange(GetLoadedEntities(tpm, Ht.LoadedSession));
            handles.AddRange(GetLoadedEntities(tpm, TpmHelpers.GetEnumerator <Ht>("ActiveSession", "SavedSession")));
            return(handles.ToArray());
        }
Example #6
0
 internal override TpmRc Execute(Tpm2 tpm, AuthSession sess, PolicyTree policy)
 {
     if (ObjectName == null)
     {
         ObjectName = AuthorizingKey.GetName();
     }
     tpm.PolicyTicket(sess, ExpirationTime, CpHash, PolicyRef,
                      ObjectName, Ticket);
     return(tpm._GetLastResponseCode());
 }
Example #7
0
 public Tbs(Tpm2Device theUnderlyingTpm, bool tpmHasRm)
 {
     TpmDevice      = theUnderlyingTpm;
     Tpm            = new Tpm2(TpmDevice);
     ContextManager = new ObjectContextManager();
     if (!tpmHasRm)
     {
         CleanTpm();
     }
 }
Example #8
0
 public Tbs(Tpm2Device theUnderlyingTpm, bool tpmHasRm)
 {
     TpmDevice = theUnderlyingTpm;
     Tpm = new Tpm2(TpmDevice);
     ContextManager = new ObjectContextManager();
     if (!tpmHasRm)
     {
         CleanTpm();
     }
 }
Example #9
0
        /// <summary>
        /// This sample demonstrates the creation and use of TPM NV-storage
        /// </summary>
        /// <param name="tpm">Reference to TPM object.</param>
        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[ownerAuth]._AllowErrors().NvUndefineSpace(TpmHandle.RhOwner, nvHandle);

            //
            // Scenario 1 - write and read a 32-byte NV-slot
            // 
            AuthValue nvAuth = AuthValue.FromRandom(8);
            tpm[ownerAuth].NvDefineSpace(TpmHandle.RhOwner, nvAuth,
                                         new NvPublic(nvHandle, TpmAlgId.Sha1,
                                                      NvAttr.Authread | NvAttr.Authwrite,
                                                      new byte[0], 32));

            //
            // Write some data
            // 
            var nvData = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7 };
            tpm[nvAuth].NvWrite(nvHandle, nvHandle, nvData, 0);

            //
            // And read it back
            // 
            byte[] nvRead = tpm[nvAuth].NvRead(nvHandle, nvHandle, (ushort)nvData.Length, 0);

            //
            // Is it correct?
            // 
            bool correct = nvData.SequenceEqual(nvRead);
            if (!correct)
            {
                throw new Exception("NV data was incorrect.");
            }

            this.textBlock.Text += "NV data written and read. ";
            
            //
            // And clean up
            // 
            tpm[ownerAuth].NvUndefineSpace(TpmHandle.RhOwner, nvHandle);
        }
Example #10
0
        /// <summary>
        /// Get the date of the specification from which the TPM was built.
        /// </summary>
        /// <param name="manufacturer"></param>
        /// <param name="year"></param>
        /// <param name="dayOfYear"></param>
        /// <param name="tpm"></param>
        public static void GetTpmInfo(Tpm2 tpm, out string manufacturer, out uint year, out uint dayOfYear)
        {
            // ReSharper disable once RedundantAssignment
            manufacturer = "";
            year         = GetProperty(tpm, Pt.Year);
            dayOfYear    = GetProperty(tpm, Pt.DayOfYear);

            uint manX = GetProperty(tpm, Pt.Manufacturer);
            var  arr  = Marshaller.GetTpmRepresentation(manX);

            manufacturer = (new System.Text.UTF8Encoding()).GetString(arr, 0, arr.Length);
        }
Example #11
0
        /// <summary>
        /// Returns error number, i.e. what is left after masking out auxiliary data
        /// (such as format selector, version, and bad parameter index) from the
        /// response code returned by TPM.
        /// </summary>
        public static TpmRc ErrorNumber(TpmRc rawResponse)
        {
            if (Tpm2.IsTbsError(rawResponse) || Tpm2.IsTssError(rawResponse))
            {
                return(rawResponse);
            }

            const uint Fmt1 = (uint)TpmRc.RcFmt1;   // Format 1 code (TPM 2 only)
            const uint Ver1 = (uint)TpmRc.RcVer1;   // TPM 1 code (format 0 only)
            const uint Warn = (uint)TpmRc.RcWarn;   // Code is a warning (format 0 only)
            uint       mask = IsFmt1(rawResponse) ? Fmt1 | 0x3F : Warn | Ver1 | 0x7F;

            return((TpmRc)((uint)rawResponse & mask));
        }
Example #12
0
        TkVerified SignApproval(Tpm2 tpm, byte[] approvedPolicy, byte[] policyRef,
                                TpmHandle hSigKey, ISigSchemeUnion scheme = null)
        {
            byte[]    name, qname;
            TpmPublic pub = tpm.ReadPublic(hSigKey, out name, out qname);

            byte[] dataToSign = Globs.Concatenate(approvedPolicy, policyRef);
            byte[] aHash      = CryptoLib.HashData(pub.nameAlg, dataToSign);

            // Create an authorization certificate for the "approvedPolicy"
            var sig = tpm.Sign(hSigKey, aHash, scheme, new TkHashcheck());

            return(tpm.VerifySignature(hSigKey, aHash, sig));
        }
Example #13
0
        internal override TpmRc Execute(Tpm2 tpm, AuthSession sess, PolicyTree policy)
        {
            byte[] nonceTpm = UseNonceTpm ? Globs.CopyData(sess.NonceTpm) : new byte[0];

            if (AuthSess != null)
            {
                tpm._SetSessions(AuthSess);
            }

            Timeout = tpm.PolicySecret(AuthEntity, sess, nonceTpm,
                                       CpHash, PolicyRef, ExpirationTime,
                                       out Ticket);
            return(tpm._GetLastResponseCode());
        }
Example #14
0
 /// <summary>
 /// Check if this TPM implements the given command.
 /// The method sends the GetCapability command the first time it is called,
 /// and reuses its results during subsequent invocations.
 /// </summary>
 /// <param name="commandCode">The command code to check.</param>
 /// <returns>true if the given command is supported by this TPM instance.</returns>
 public bool IsImplemented(TpmCc commandCode)
 {
     if (ImplementedCommands == null || ImplementedCommands.Length == 0)
     {
         ICapabilitiesUnion caps;
         uint totalCommands = Tpm2.GetProperty(Tpm, Pt.TotalCommands);
         Tpm.GetCapability(Cap.Commands, (uint)TpmCc.First, totalCommands, out caps);
         ImplementedCommands = Globs.ConvertAll((caps as CcaArray).commandAttributes,
                                                cmdAttr => (TpmCc)(cmdAttr & CcAttr.commandIndexBitMask))
                               .ToArray();
         Debug.Assert(ImplementedCommands.Length != 0);
     }
     return(ImplementedCommands.Contains(commandCode));
 }
Example #15
0
        /// <summary>
        /// Run a path on the policy tree.  The path is identified by the leaf identifier string. A session is
        /// created and returned. If allowErrors is true then errors returned do not cause an exception (but
        /// are returned in the response code).
        /// </summary>
        /// <param name="tpm"></param>
        /// <param name="policySession"></param>
        /// <param name="branchToEvaluate"></param>
        /// <param name="allowErrors"></param>
        /// <returns></returns>
        public TpmRc RunPolicy(Tpm2 tpm, PolicyTree policyTree, string branchToEvaluate = null, bool allowErrors = false)
        {
            policyTree.AllowErrorsInPolicyEval = allowErrors;

            PolicyAce leafAce = null;

            // First, check that the policy is OK.
            policyTree.CheckPolicy(branchToEvaluate, ref leafAce);
            if (leafAce == null)
            {
                Globs.Throw("RunPolicy: Branch identifier " + branchToEvaluate + " does not exist");
            }

            var responseCode = TpmRc.Success;

            try
            {
                if (allowErrors)
                {
                    tpm._DisableExceptions();
                }

                tpm._InitializeSession(this);

                // Walk up the tree from the leaf..
                PolicyAce nextAce = leafAce;
                while (nextAce != null)
                {
                    responseCode = nextAce.Execute(tpm, this, policyTree);

                    if (responseCode != TpmRc.Success)
                    {
                        break;
                    }

                    // ..and continue along the path to the root
                    nextAce = nextAce.PreviousAce;
                }
            }
            finally
            {
                if (allowErrors)
                {
                    tpm._EnableExceptions();
                }
            }

            return(responseCode);
        }
Example #16
0
        internal override TpmRc Execute(Tpm2 tpm, AuthSession sess, PolicyTree policy)
        {
            byte[] nonceTpm = UseNonceTpm ? Globs.CopyData(sess.NonceTpm) : new byte[0];

            TpmHandle sigKey;

            // If we have both the authorizing signature and the corresponding
            // signing key handle, we are good to go.
            if (AuthSig == null)
            {
                var dataToSign = new Marshaller();
                dataToSign.Put(nonceTpm, "");

                // If we have a signing key we can build the challenge here
                // (else we need to call out)
                if (SwSigningKey != null)
                {
                    dataToSign.Put(ExpirationTime, "");
                    dataToSign.Put(CpHash, "");
                    dataToSign.Put(PolicyRef, "");
                    // Just ask the key to sign the challenge
                    AuthSig = SwSigningKey.Sign(dataToSign.GetBytes());
                    sigKey  = tpm.LoadExternal(null, SigningKeyPub, TpmRh.Owner);
                }
                else
                {
                    TpmPublic verifier;
                    AuthSig = AssociatedPolicy.ExecuteSignerCallback(this, nonceTpm,
                                                                     out verifier);
                    sigKey = tpm.LoadExternal(null, verifier, TpmRh.Owner);
                }
            }
            else
            {
                sigKey = tpm.LoadExternal(null, SigningKeyPub, TpmRh.Owner);
            }
            Timeout = tpm.PolicySigned(sigKey, sess, nonceTpm,
                                       CpHash, PolicyRef, ExpirationTime,
                                       AuthSig, out Ticket);

            TpmRc responseCode = tpm._GetLastResponseCode();

            tpm.FlushContext(sigKey);
            if (!KeepAuth)
            {
                AuthSig = null;
            }
            return(responseCode);
        }
Example #17
0
        public static byte[] GetPcrProperty(Tpm2 tpm, PtPcr prop)
        {
            ICapabilitiesUnion caps;

            tpm.GetCapability(Cap.PcrProperties, (uint)prop, 1, out caps);
            TaggedPcrSelect[] props = (caps as TaggedPcrPropertyArray).pcrProperty;
            if (props.Length == 0)
            {
                return(null);
            }
            if (props.Length != 1)
            {
                Globs.Throw("Unexpected return from GetCapability");
            }
            return(props[0].pcrSelect);
        }
Example #18
0
        public static uint GetProperty(Tpm2 tpm, Pt tagToGet)
        {
            ICapabilitiesUnion caps;

            tpm.GetCapability(Cap.TpmProperties, (uint)tagToGet, 1, out caps);
            var props = (TaggedTpmPropertyArray)caps;

            TaggedProperty[] arr = props.tpmProperty;
            if (arr.Length != 1)
            {
                throw new Exception("Unexpected return from GetCapability");
            }

            uint val = arr[0].value;

            return(val);
        }
Example #19
0
        /// <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>
        static void Main()
        {
            try
            {
                //
                // Create the device according to the selected connection.
                // 
                Tpm2Device tpmDevice = new TcpTpmDevice(DefaultSimulatorName, DefaultSimulatorPort);
                //
                // 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 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);

                ResetDALogic(tpm);
                ResourceManager(tpm);
                PowerAndLocality(tpm);

                //
                // Clean up.
                // 
                tpm.Dispose();
            }
            catch (Exception e)
            {
                Console.WriteLine("Exception occurred: {0}", e.Message);
            }

            Console.WriteLine("Press Any Key to continue.");
            Console.ReadLine();
        }
Example #20
0
        private TpmHandle[] GetLoadedEntities(Tpm2 tpm, Ht rangeToQuery)
        {
            const uint         maxHandles = UInt32.MaxValue;
            ICapabilitiesUnion h;
            byte moreData = tpm.GetCapability(Cap.Handles, ((uint)rangeToQuery) << 24, maxHandles, out h);

            if (moreData != 0)
            {
                throw new NotImplementedException("Too much data returned");
            }
            if (h.GetType() != typeof(HandleArray))
            {
                throw new Exception("Incorrect type");
            }
            var handles = (HandleArray)h;

            return(handles.handle);
        }
Example #21
0
        /// <summary>
        /// Returns the cached name of an entity referenced by this handle. If the
        /// name is not cached yet, retrieves it from the TPM (for a transient or
        /// persistent object, or NV index) or computes it (for session, PCR or
        /// permanent handles).
        /// </summary>
        public byte[] GetName(Tpm2 tpm)
        {
            Ht ht = GetType();

            if (_Name == null)
            {
                if (ht == Ht.NvIndex)
                {
                    tpm.NvReadPublic(this, out _Name);
                    return(_Name);
                }
                if (ht == Ht.Transient || ht == Ht.Persistent)
                {
                    byte[] qName;
                    tpm.ReadPublic(this, out _Name, out qName);
                    return(_Name);
                }
            }
            return(GetName());
        }
Example #22
0
        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();
        }
Example #23
0
        public static uint GetProperty(Tpm2 tpm, Pt prop)
        {
            ICapabilitiesUnion caps;

            tpm.GetCapability(Cap.TpmProperties, (uint)prop, 1, out caps);
            var props = (TaggedTpmPropertyArray)caps;

            TaggedProperty[] arr = props.tpmProperty;
            if (arr.Length != 1)
            {
                Globs.Throw("Unexpected return from GetCapability");
                if (arr.Length == 0)
                {
                    return(0);
                }
            }

            uint val = arr[0].value;

            return(val);
        }
Example #24
0
        TpmRc Execute(Tpm2 tpm, AuthSession sess, PolicyTree policy)
        {
#if false
            if (Ticket == null)
            {
                // create a dummy ticket = e.g. for a trial session
                Ticket = new TkVerified(TpmRh.Owner, new byte[0]);
            }
#endif

            if (ParamsCallback != null)
            {
                ParamsCallback(tpm, sess, PolicyToReplace, PolicyRef, SigKeyName, Ticket);
            }
            if (policy.AllowErrorsInPolicyEval)
            {
                tpm._AllowErrors();
            }
            tpm.PolicyAuthorize(sess, PolicyToReplace, PolicyRef, SigKeyName, Ticket);

            return(tpm._GetLastResponseCode());
        }
Example #25
0
        /// <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();
        }
Example #26
0
        /// <summary>
        /// Some policies can be evaluated solely from public parts of the policy.
        /// Others needs a private keyholder to sign some data. Tpm2Lib provides 
        /// a callback facility for these cases.  
        /// 
        /// This second sample illustrates the use of callbacks to provide authData.
        /// </summary>
        /// <param name="tpm">Reference to the TPM object to use.</param>
        static void PolicyEvaluationWithCallback2(Tpm2 tpm)
        {
            Console.WriteLine("Policy evaluation with callback sample 2.");

            //
            // Check if policy commands are implemented by TPM. This list
            // could include all the other used commands as well.
            // This check here makes sense for policy commands, because
            // usually a policy has to be executed in full. If a command
            // out of the chain of policy commands is not implemented in the
            // TPM, the policy cannot be satisfied.
            // 
            var usedCommands = new[] {
                                        TpmCc.PolicySecret,
                                        TpmCc.PolicyGetDigest,
                                        TpmCc.PolicyRestart
            };
            foreach (var commandCode in usedCommands)
            {
                if (!tpm.Helpers.IsImplemented(commandCode))
                {
                    Console.WriteLine("Cancel Policy evaluation callback 2 sample, because command {0} is not implemented by TPM.", commandCode);
                    return;
                }
            }

            //
            // Create an object with an AuthValue. The type of object is immaterial
            // (it can even be the owner). In order to construct the policy we will 
            // need the name and to prove that we know the AuthVal.
            // 
            _publicAuthorizationValue = AuthValue.FromRandom(10);
            var dataToSeal = new byte[] { 1, 2, 3, 4 };
            _publicSealedObjectHandle = CreateSealedPrimaryObject(tpm,
                                                                  dataToSeal,
                                                                  _publicAuthorizationValue, 
                                                                  null);
            byte[] objectName = _publicSealedObjectHandle.Name;

            var policy = new PolicyTree(TpmAlgId.Sha256);

            policy.Create(
                new PolicyAce[]
                    {
                            new TpmPolicySecret(objectName,     // Name of the obj that we will prove authData
                                                true,           // Include nonceTpm
                                                new byte[0],    // Not bound to a cpHash
                                                new byte[0],    // Null policyRef
                                                0),             // Never expires (in this session)
                            "leaf"                              // Name for this ACE
                    });

            TpmHash expectedHash = policy.GetPolicyDigest();

            //
            // We are about to ask for the session to be evaluated, but in order
            // to process TpmPolicySecret the caller will have to prove knowledge of 
            // the authValue associated with objectName. In this first version we
            // do this with PWAP.
            // 
            policy.SetPolicySecretCallback(PolicySecretCallback);
            AuthSession authSession = tpm.StartAuthSessionEx(TpmSe.Policy, TpmAlgId.Sha256);
            authSession.RunPolicy(tpm, policy, "leaf");

            //
            // The policy evaluated.  But is the digest what we expect?
            // 
            byte[] digestIs = tpm.PolicyGetDigest(authSession.Handle);
            if (expectedHash != digestIs)
            {
                throw new Exception("Incorrect PolicyDigest");
            }

            //
            // And now do the same thing but with an HMAC session.
            // 
            _sharedTpm = tpm;
            tpm.PolicyRestart(authSession.Handle);
            policy.SetPolicySecretCallback(PolicySecretCallback2);
            authSession.RunPolicy(tpm, policy, "leaf");
            _sharedTpm = null;

            //
            // The policy evaluated. But is the digest what we expect?
            // 
            digestIs = tpm.PolicyGetDigest(authSession.Handle);
            if (expectedHash != digestIs)
            {
                throw new Exception("Incorrect PolicyDigest");
            }
            Console.WriteLine("TpmPolicySignature evaluated.");

            tpm.FlushContext(authSession.Handle);
        }
Example #27
0
 public ByteArrayComparer(Tpm2 tpm)
 {
     my_tpm = tpm;
 }
Example #28
0
 internal override TpmRc Execute(Tpm2 tpm, AuthSession sess, PolicyTree policy)
 {
     Globs.Throw("Do not include PolicyRestart in running policies");
     return(TpmRc.Policy);
 }
Example #29
0
 internal override TpmRc Execute(Tpm2 tpm, AuthSession sess, PolicyTree policy)
 {
     tpm.PolicyPhysicalPresence(sess);
     return(tpm._GetLastResponseCode());
 }
Example #30
0
 internal override TpmRc Execute(Tpm2 tpm, AuthSession sess, PolicyTree policy)
 {
     tpm.PolicyCounterTimer(sess, OperandB, Offset, Operation);
     return(tpm._GetLastResponseCode());
 }
Example #31
0
 internal override TpmRc Execute(Tpm2 tpm, AuthSession sess, PolicyTree policy)
 {
     tpm.PolicyLocality(sess, AllowedLocality);
     return(tpm._GetLastResponseCode());
 }
Example #32
0
        /// <summary>
        /// This sample demonstrates the creation and use of a storage root key that 
        /// behaves like the Storage Root Key (SRK) defined in TPM1.2.
        /// To do this we need to create a new primary, and then use EvictControl
        /// to make it NV-resident.
        /// </summary>
        /// <param name="tpm">Reference to TPM object</param>
        static void StorageRootKey(Tpm2 tpm)
        {
            //
            // This template asks the TPM to create an 2048 bit RSA storage key 
            // with an associated AES key for symmetric data protection.  The term 
            // "SRKs" is not used in TPM2.0, but we use it here to 
            // not 
            // 
            var srkTemplate = new TpmPublic(TpmAlgId.Sha1,                      // Name algorithm
                                            ObjectAttr.Restricted   |           // Storage keys must be restricted
                                            ObjectAttr.Decrypt      |           // Storage keys are Decrypt keys
                                            ObjectAttr.FixedParent  | ObjectAttr.FixedTPM | // Non-duplicable (like 1.2)
                                            ObjectAttr.UserWithAuth | ObjectAttr.SensitiveDataOrigin,
                                            new byte[0],                        // No policy
                                            new RsaParms(new SymDefObject(TpmAlgId.Aes, 128, TpmAlgId.Cfb),
                                                         new NullAsymScheme(),  // No signature
                                                         2048, 0),              // 2048-bit RSA
                                            new Tpm2bPublicKeyRsa());
            //
            // Authorization for the key we are about to create
            // 
            var srkAuth = new byte[0];

            AuthValue childAuthVal = AuthValue.FromRandom(8);
            TssObject swKey = TssObject.CreateStorageParent(srkTemplate, childAuthVal);

            TpmPublic srkPublic;
            CreationData srkCreationData;
            TkCreation srkCreationTicket;
            byte[] srkCreationHash;

            //
            // Ask the TPM to create a new primary RSA/AES primary storage key
            // 
            TpmHandle keyHandle = tpm[_ownerAuth].CreatePrimary(
                TpmHandle.RhOwner,                          // In the owner-hierarchy
                new SensitiveCreate(srkAuth, new byte[0]),  // With this auth-value
                srkTemplate,                                // Describes key
                new byte[0],                                // For creation ticket
                new PcrSelection[0],                        // For creation ticket
                out srkPublic,                              // Out pubKey and attrs
                out srkCreationData,                        // Not used here
                out srkCreationHash,                        //      Ibid
                out srkCreationTicket);                     //      Ibid
                                                                
            //
            // print out text-versions of the public key just created
            // 
            Console.WriteLine("New SRK public key\n" + srkPublic.ToString());

            //
            // The caller provides the handle for persistent keys
            // 
            TpmHandle srkHandle = TpmHandle.Persistent(0x5000);

            //
            // Ae will make the "SRK" persistent in an NV-slot, so clean up anything
            // that is already there
            // 
            tpm[_ownerAuth]._AllowErrors().EvictControl(TpmHandle.RhOwner, srkHandle, srkHandle);
            TpmRc lastError = tpm._GetLastResponseCode();

            //
            // Make the SRK NV-resident
            // 
            tpm[_ownerAuth].EvictControl(TpmHandle.RhOwner, keyHandle, srkHandle);

            Console.WriteLine("SRK is persistent now.");
        }
Example #33
0
        /// <summary>
        /// This sample illustrates the creation and use of an RSA signing key to 
        /// "quote" PCR state
        /// </summary>
        /// <param name="tpm">Reference to the TPM object.</param>
        static void QuotePcrs(Tpm2 tpm)
        {
            //
            // First use a library routine to create an RSA/AES primary storage key
            // with null user-auth.
            // 
            TpmPublic rsaPrimaryPublic;
            var primaryAuth = new byte[0];
            TpmHandle primHandle = CreateRsaPrimaryStorageKey(tpm, primaryAuth, out rsaPrimaryPublic);

            //
            // Template for a signing key.  We will make the key restricted so that we 
            // can quote with it too.
            // 
            var signKeyPubTemplate = new TpmPublic(TpmAlgId.Sha1,
                                                   ObjectAttr.Sign | ObjectAttr.Restricted |      // A "quoting" key
                                                   ObjectAttr.FixedParent | ObjectAttr.FixedTPM | // Non-duplicable
                                                   ObjectAttr.UserWithAuth |                      // Authorize with auth-data
                                                   ObjectAttr.SensitiveDataOrigin,                // TPM will create a new key
                                                   new byte[0],
                                                   new RsaParms(new SymDefObject(), new SchemeRsassa(TpmAlgId.Sha1), 2048, 0),
                                                   new Tpm2bPublicKeyRsa());
            //
            // Auth-data for new key
            // 
            var userAuth = new byte[] { 1, 2, 3, 4 };
            var sensCreate = new SensitiveCreate(userAuth, new byte[0]);

            //
            // Creation data (not used in this sample)
            // 
            CreationData childCreationData;
            TkCreation creationTicket;
            byte[] creationHash;

            //
            // Create the key
            // 
            TpmPublic keyPub;
            TpmPrivate keyPriv = tpm[primaryAuth].Create(primHandle,          // Child of primary key created above
                                                         sensCreate,          // Auth-data
                                                         signKeyPubTemplate,  // Template created above
                                                         new byte[0],         // Other parms are not used here
                                                         new PcrSelection[0],
                                                         out keyPub,
                                                         out childCreationData, out creationHash, out creationTicket);

            Console.WriteLine("New public key\n" + keyPub.ToString());

            //
            // Load the key as a child of the primary that it 
            // was created under.
            // 
            TpmHandle signHandle = tpm[primaryAuth].Load(primHandle, keyPriv, keyPub);

            //
            // Note that Load returns the "name" of the key and this is automatically
            // associated with the handle.
            // 
            Console.WriteLine("Name of key:" + BitConverter.ToString(signHandle.Name));

            //
            // Aome data to quote
            // 
            TpmHash hashToSign = TpmHash.FromData(TpmAlgId.Sha1, new byte[] { 4, 3, 2, 1 });

            //
            // PCRs to quote.  SHA-1 bank, PCR-indices 1, 2, and 3
            // 
            var pcrsToQuote = new PcrSelection[] 
            {
                new PcrSelection(TpmAlgId.Sha, new uint[] { 1, 2, 3 })
            };

            //
            // Ask the TPM to quote the PCR (and the nonce).  The TPM
            // returns the quote-signature and the data that was signed
            // 
            ISignatureUnion quoteSig;
            Attest quotedInfo = tpm[userAuth].Quote(signHandle,
                                                    hashToSign.HashData,
                                                    new SchemeRsassa(TpmAlgId.Sha1),
                                                    pcrsToQuote,
                                                    out quoteSig);
            //
            // Print out what was quoted
            // 
            var info = (QuoteInfo)quotedInfo.attested;
            Console.WriteLine("PCRs that were quoted: "    +
                              info.pcrSelect[0].ToString() +
                              "\nHash of PCR-array: "      +
                              BitConverter.ToString(info.pcrDigest));

            //
            // Read the PCR to check the quoted value
            // 
            PcrSelection[] outSelection;
            Tpm2bDigest[] outValues;
            tpm.PcrRead(new PcrSelection[] {
                            new PcrSelection(TpmAlgId.Sha, new uint[] { 1, 2, 3 }) 
                        },
                        out outSelection,
                        out outValues);

            //
            // Use the Tpm2Lib library to validate the quote against the
            // values just read.
            // 
            bool quoteOk = keyPub.VerifyQuote(TpmAlgId.Sha1,
                                              outSelection,
                                              outValues,
                                              hashToSign.HashData,
                                              quotedInfo,
                                              quoteSig);
            if (!quoteOk)
            {
                throw new Exception("Quote did not validate");
            }

            Console.WriteLine("Quote correctly validated.");

            //
            // Test other uses of the signing key.  A restricted key can only
            // sign data that the TPM knows does not start with a magic
            // number (that identifies TPM internal data).  So this does not 
            // work
            //
            var nullProof = new TkHashcheck(TpmHandle.RhNull, new byte[0]);
            tpm[userAuth]._ExpectError(TpmRc.Ticket).Sign(signHandle,
                                                          hashToSign.HashData,
                                                          new SchemeRsassa(TpmAlgId.Sha1),
                                                          nullProof);
            //
            // But if we ask the TPM to hash the same data and then sign it 
            // then the TPM can be sure that the data is safe, so it will 
            // sign it.
            // 
            TkHashcheck safeHashTicket;
            TpmHandle hashHandle = tpm.HashSequenceStart(_nullAuth, TpmAlgId.Sha1);

            //
            // The ticket is only generated if the data is "safe."
            // 
            tpm[_nullAuth].SequenceComplete(hashHandle,
                                            new byte[] { 4, 3, 2, 1 },
                                            TpmHandle.RhOwner,
                                            out safeHashTicket);
            //
            // This will now work because the ticket proves to the 
            // TPM that the data that it is about to sign does not 
            // start with TPM_GENERATED
            // 
            ISignatureUnion sig = tpm[userAuth].Sign(signHandle,
                                                     hashToSign.HashData,
                                                     new SchemeRsassa(TpmAlgId.Sha1),
                                                     safeHashTicket);
            //
            // And we can verify the signature
            // 
            bool sigOk = keyPub.VerifySignatureOverData(new byte[] { 4, 3, 2, 1 }, sig);
            if (!sigOk)
            {
                throw new Exception("Signature did not verify");
            }

            Console.WriteLine("Signature verified.");

            //
            // Clean up
            // 
            tpm.FlushContext(primHandle);
            tpm.FlushContext(signHandle);
        }
Example #34
0
        /// <summary>
        /// Use a hash sequence to concatenate and hash data that is bigger then
        /// the communication buffer to the TPM.
        /// </summary>
        /// <param name="tpm">Reference to the TPM object.</param>
        static void HashSequence(Tpm2 tpm)
        {
            //
            // Create an auth-value to control later access to the hash object. 
            // The AuthValue class is a Tpm2Lib-provided helper object for managing
            // authorization data.  Here we ask the library to create a 10-byte
            // random array.
            // 
            AuthValue authVal = AuthValue.FromRandom(10);

            //
            // Create a hash sequence-object with the auth-value provided and
            // based on SHA-1. This command returns a uint identifier that we call a handle.
            // 
            TpmHandle hashHandle = tpm.HashSequenceStart(authVal, TpmAlgId.Sha1);

            //
            // Hash some data using the hash sequence object just created.
            // It is normally the case that the use of TPM internal objects
            // must be "authorized" by proof-of-knowledge of the authorization 
            // value that was set when the object was created. Authorization
            // is communicated using a TPM construct called a "session." 
            // Every handle that requires authorization requires a session
            // that conveys knowledge of the auth-value (or other authorization).
            //
            // The specific style of session used here is a "password authorization
            // session, or PWAP session, where the password is communicated
            // in plain text.
            // 
            // Three styles of session creation are demonstrated.  
            // Style 1 (not preferred).  The method _SetSessions() tells Tpm2Lib
            // to use the authorization value authVal in a PWAP session 
            // 
            tpm._SetSessions(authVal);
            tpm[authVal].SequenceUpdate(hashHandle, new byte[] { 0, 1 });

            //
            // Style 2 (not preferred).  The method _SetSessions() returns "this"
            // so the two lines above can be condensed.  tpm._SetSessions(authVal);
            // 
            tpm._SetSessions(authVal).SequenceUpdate(hashHandle, new byte[] { 2, 3 });

            //
            // Style 3 - RECOMMENDED
            // In the command sequence below the [authValue] construct is
            // NOT an array-accessor.  Instead it is shorthand to associate 
            // a list of authorization sessions with the command (one session
            // in this case.
            // 
            tpm[authVal].SequenceUpdate(hashHandle, new byte[] { 4, 5 });
            tpm[authVal].SequenceUpdate(hashHandle, new byte[] { 6, 7 });

            //
            // Add the final data block
            // 
            TkHashcheck validation;
            byte[] hashedData = tpm[authVal].SequenceComplete(hashHandle,
                                                              new byte[] { 4, 5 },
                                                              TpmHandle.RhOwner,
                                                              out validation);

            Console.WriteLine("Hashed data (Sequence): " + BitConverter.ToString(hashedData));
        }
Example #35
0
        /// <summary>
        /// This sample demonstrates the async interface to the TPM for selected slow operations.
        /// await-async is preferred when calling slow TPM functions on a UI-thread.  Only a few TPM
        /// functions have an async-form.
        /// </summary>
        /// <param name="tpm">Reference to TPM object</param>
        /// <param name="Event">Synchronization object to signal calling function when we're done.</param>
        static async void PrimarySigningKeyAsync(Tpm2 tpm, AutoResetEvent Event)
        {
            //
            // 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 };

            //
            // Ask the TPM to create a new primary RSA signing key
            // 
            var newPrimary = await tpm[_ownerAuth].CreatePrimaryAsync(
                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

            //
            // Print out text-versions of the public key just created
            // 
            Console.WriteLine("New public key\n" + newPrimary.outPublic.ToString());

            //
            // Use the key to sign some data
            // 
            byte[] message = Encoding.Unicode.GetBytes("ABC");
            TpmHash dataToSign = TpmHash.FromData(TpmAlgId.Sha1, message);
            var sig = await tpm[keyAuth].SignAsync(newPrimary.objectHandle,            // Handle of signing key
                                                   dataToSign.HashData,                // Data to sign
                                                   new SchemeRsassa(TpmAlgId.Sha1),    // Default scheme
                                                   TpmHashCheck.NullHashCheck());
            //
            // Print the signature. A different structure is returned for each 
            // signing scheme, so cast the interface to our signature type.
            // 
            var actualSig = (SignatureRsassa)sig;
            Console.WriteLine("Signature: " + BitConverter.ToString(actualSig.sig));

            //
            // Clean up
            // 
            tpm.FlushContext(newPrimary.objectHandle);

            //
            // Tell caller, we're done.
            // 
            Event.Set();
        }
Example #36
0
        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;
            }
        }
Example #37
0
 private TpmHandle[] GetAllLoadedEntities(Tpm2 tpm)
 {
     var handles = new List<TpmHandle>();
     handles.AddRange(GetLoadedEntities(tpm, Ht.Transient));
     handles.AddRange(GetLoadedEntities(tpm, Ht.LoadedSession));
     handles.AddRange(GetLoadedEntities(tpm, TpmHelpers.GetEnumerator<Ht>("ActiveSession", "SavedSession")));
     return handles.ToArray();
 }
Example #38
0
 private TpmHandle[] GetLoadedEntities(Tpm2 tpm, Ht rangeToQuery)
 {
     const uint maxHandles = UInt32.MaxValue;
     ICapabilitiesUnion h;
     byte moreData = tpm.GetCapability(Cap.Handles, ((uint)rangeToQuery) << 24, maxHandles, out h);
     if (moreData != 0)
     {
         throw new NotImplementedException("Too much data returned");
     }
     if (h.GetType() != typeof (HandleArray))
     {
         throw new Exception("Incorrect type");
     }
     var handles = (HandleArray)h;
     return handles.handle;
 }
Example #39
0
        /// <summary>
        /// This sample illustrates the use of a TpmPolicyOr.
        /// </summary>
        static void PolicyOr(Tpm2 tpm)
        {
            Console.WriteLine("PolicyOr sample:");

            //
            // Check if policy commands are implemented by TPM. This list
            // could include all the other used commands as well.
            // This check here makes sense for policy commands, because
            // usually a policy has to be executed in full. If a command
            // out of the chain of policy commands is not implemented in the
            // TPM, the policy cannot be satisfied.
            // 
            var usedCommands = new[] {
                                        TpmCc.PolicyLocality,
                                        TpmCc.PolicyPCR,
                                        TpmCc.PolicyAuthValue
            };
            foreach (var commandCode in usedCommands)
            {
                if (!tpm.Helpers.IsImplemented(commandCode))
                {
                    Console.WriteLine("Cancel Policy OR sample, because command {0} is not implemented by TPM.", commandCode);
                    return;
                }
            }

            var pcrs = new uint[] { 1, 2, 3 };
            var sel = new PcrSelection(TpmAlgId.Sha, pcrs);

            PcrSelection[] selOut;
            Tpm2bDigest[] pcrValues;

            //
            // First read the PCR values
            // 
            tpm.PcrRead(new[] { sel }, out selOut, out pcrValues);

            //
            // Save the current PCR values in a convenient data structure
            // 
            var expectedPcrVals = new PcrValueCollection(selOut, pcrValues);

            //
            // Tpm2Lib encapsulates a set of policy assertions as the PolicyTree class.  
            // 
            var policyTree = new PolicyTree(TpmAlgId.Sha256);

            //
            // First branch of PolicyOr
            // 
            var branch1 = new PolicyAce[]
            {
                new TpmPolicyLocality(LocalityAttr.TpmLocZero),
                new TpmPolicyPcr(expectedPcrVals), 
                "branch_1"
            };

            //
            // Second branch of PolicyOr
            //
            var branch2 = new PolicyAce[]
            {
                new TpmPolicyAuthValue(),
                "branch_2"
            };

            //
            // Create the policy. CreateNormalizedPolicy takes an array-of-arrays
            // of PolicyACEs that are to be OR'ed together (the branches themselves cannot
            // contain TpmPOlicyOrs). The library code constructs a policy tree with 
            // minimum number of TpmPolicyOrs at the root.  
            // 
            policyTree.CreateNormalizedPolicy(new[] {branch1, branch2});

            //
            // Ask Tpm2Lib for the expected policy-hash for this policy
            // 
            TpmHash expectedPolicyHash = policyTree.GetPolicyDigest();

            //
            // Create a sealed primary object with the policy-hash we just calculated
            // 
            var dataToSeal = new byte[] { 1, 2, 3, 4, 5, 4, 3, 2, 1 };
            var authVal = new byte[] { 1, 2 };
            TpmHandle primHandle = CreateSealedPrimaryObject(tpm, 
                                                             dataToSeal, 
                                                             authVal,
                                                             expectedPolicyHash.HashData);
            //
            // Create an actual TPM policy session to evaluate the policy
            // 
            AuthSession session = tpm.StartAuthSessionEx(TpmSe.Policy, TpmAlgId.Sha256);

            //
            // Run the policy on the TPM
            // 
            session.RunPolicy(tpm, policyTree, "branch_1");

            //
            // And unseal the object
            // 
            byte[] unsealedData = tpm[session].Unseal(primHandle);
            Console.WriteLine("Unsealed data for branch_1: " + BitConverter.ToString(unsealedData));
            
            //
            // Now run the other branch
            // 
            tpm.PolicyRestart(session.Handle);
            session.RunPolicy(tpm, policyTree, "branch_2");

            //
            // And the session will be unusable
            // 
            unsealedData = tpm[session].Unseal(primHandle);
            Console.WriteLine("Unsealed data for branch_2: " + BitConverter.ToString(unsealedData));

            //
            // Clean up
            // 
            tpm.FlushContext(session.Handle);
            tpm.FlushContext(primHandle);
        }
Example #40
0
 /// <summary>
 /// Very simple hash calculation. 
 /// We ask the TPM to calculate the hash of a 3-byte array.
 /// </summary>
 /// <param name="tpm">Reference to the TPM object.</param>
 static void SimpleHash(Tpm2 tpm)
 {
     TkHashcheck validation;
     byte[] hashData = tpm.Hash(new byte[] { 1, 2, 3 },   // Data to hash
                                TpmAlgId.Sha256,          // Hash algorithm
                                TpmHandle.RhOwner,        // Hierarchy for ticket (not used here)
                                out validation);          // Ticket (not used in this example)
     Console.WriteLine("Hashed data (Hash): " + BitConverter.ToString(hashData));
 }
Example #41
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
            // 
            AuthValue authVal = AuthValue.FromRandom(8);
            TpmHandle hashHandle = tpm.HashSequenceStart(authVal, 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.
            // 
            TkHashcheck validate;
            tpm[s0].SequenceUpdate(hashHandle, new byte[] { 0, 2, 1 });
            byte[] hashedData = tpm[s0].SequenceComplete(hashHandle,
                                                         new byte[] { 2, 3, 4 },
                                                         TpmHandle.RhOwner,
                                                         out validate);

            Console.WriteLine("Hashed data (HMAC authorized sequence): " + BitConverter.ToString(hashedData));
            tpm.FlushContext(s0.Handle);
        }
Example #42
0
        /// <summary>
        /// Create an RSA primary storage key in the storage hierarchy and return the key-handle 
        /// to the caller.  The key will be RSA2048 with a SHA256-name algorithm.  The caller can 
        /// provide user-auth. The caller is responsible for disposing of this key.
        /// </summary>
        /// <returns></returns>
        static TpmHandle CreateRsaPrimaryStorageKey(Tpm2 tpm, byte[] auth, out TpmPublic newKeyPub)
        {
            //
            // Creation parameters (no external data for TPM-created objects)
            // 
            var sensCreate = new SensitiveCreate(auth,         // Auth-data provided by the caller
                                                 new byte[0]); // No external data (the TPM will create the new key).

            var parms = new TpmPublic(TpmAlgId.Sha256, 
                                      ObjectAttr.Restricted   | ObjectAttr.Decrypt  |  // Storage key
                                      ObjectAttr.FixedParent  | ObjectAttr.FixedTPM |  // Non-duplicable
                                      ObjectAttr.UserWithAuth | ObjectAttr.SensitiveDataOrigin,
                                      new byte[0], // No policy, and Storage key should be RSA + AES128
                                      new RsaParms(new SymDefObject(TpmAlgId.Aes, 128, TpmAlgId.Cfb),
                                                   new NullAsymScheme(), 2048, 0),
                                      new Tpm2bPublicKeyRsa());

            //
            // The following are returned by the TPM in CreatePrimary (and Create)
            // they are not used in this sample.
            // 
            CreationData creationData;
            TkCreation creationTicket;
            byte[] creationHash;

            TpmHandle primHandle = tpm[_ownerAuth].CreatePrimary(TpmHandle.RhOwner,    // In storage hierarchy
                                                                 sensCreate,           // UserAuth
                                                                 parms,                // Creation parms set above
                                                                 //
                                                                 // The following parameters influence the creation of the 
                                                                 // creation-ticket. They are not used in this sample
                                                                 //
                                                                 new byte[0],          // Null outsideInfo
                                                                 new PcrSelection[0],  // Do not record PCR-state
                                                                 out newKeyPub,        // Our outs
                                                                 out creationData, out creationHash, out creationTicket);
            return primHandle;
        }
Example #43
0
 internal override TpmRc Execute(Tpm2 tpm, AuthSession sess, PolicyTree policy)
 {
     tpm.PolicyNameHash(sess, NameHash);
     return(tpm._GetLastResponseCode());
 }
Example #44
0
        /// <summary>
        /// This sample demonstrates the use of the TPM Platform Configuration 
        /// Registers (PCR). Tpm2Lib provides several features to model PCR
        /// semantics.
        /// </summary>
        /// <param name="tpm">Reference to the TPM object.</param>
        static void Pcrs(Tpm2 tpm)
        {
            //
            // Read the value of the SHA1 PCR 1 and 2
            // 
            var valuesToRead = new PcrSelection[] 
                {
                    new PcrSelection(TpmAlgId.Sha1, new uint[] {1, 2})
                };

            PcrSelection[] valsRead;
            Tpm2bDigest[] values;

            tpm.PcrRead(valuesToRead, out valsRead, out values);

            //
            // Check that what we read is what we asked for (the TPM does not 
            // guarantee this)
            // 
            if (valsRead[0] != valuesToRead[0])
            {
                Console.WriteLine("Unexpected PCR-set");
            }

            //
            // Print out PCR-1
            // 
            var pcr1 = new TpmHash(TpmAlgId.Sha1, values[0].buffer);
            Console.WriteLine("PCR1: " + pcr1);

            //
            // Extend (event) PCR[1] in the TPM and in the external library and
            // see if they match
            //
            var dataToExtend = new byte[] { 0, 1, 2, 3, 4 };

            //
            // Note that most PCR must be authorized with "null" authorization
            // 
            tpm[_nullAuth].PcrEvent(TpmHandle.Pcr(1), dataToExtend);

            //
            // And read the current value
            // 
            tpm.PcrRead(valuesToRead, out valsRead, out values);

            //
            // Update the "simulated" PCR
            // 
            pcr1.Event(dataToExtend);

            //
            // And see whether the PCR has the value we expect
            // 
            if (pcr1 != values[0].buffer)
            {
                throw new Exception("Event did not work");
            }

            //
            // Update a resettable PCR
            // 
            tpm[_nullAuth].PcrEvent(TpmHandle.Pcr(16), new byte[] { 1, 2 });

            //
            // And reset it
            // 
            tpm[_nullAuth].PcrReset(TpmHandle.Pcr(16));

            //
            // And check that it is indeed zero
            // 
            tpm.PcrRead(new PcrSelection[] {
                            new PcrSelection(TpmAlgId.Sha1, new uint[] {16})
                        }, 
                        out valsRead,
                        out values);

            //
            // Did it reset?
            // 
            if (TpmHash.ZeroHash(TpmAlgId.Sha1) != values[0].buffer)
            {
                throw new Exception("PCR did not reset");
            }

            Console.WriteLine("PCR sample finished.");
        }
Example #45
0
        public static uint GetProperty(Tpm2 tpm, Pt tagToGet)
        {
            ICapabilitiesUnion caps;
            tpm.GetCapability(Cap.TpmProperties, (uint)tagToGet, 1, out caps);
            var props = (TaggedTpmPropertyArray)caps;
            TaggedProperty[] arr = props.tpmProperty;
            if (arr.Length != 1)
            {
                throw new Exception("Unexpected return from GetCapability");
            }

            uint val = arr[0].value;
            return val;
        }
Example #46
0
        /// <summary>
        /// This sample illustrates the use of a simple TPM policy session. The policy demands
        /// PCR 1, 2, 3 set to current values, and the command be issued at locality zero.
        /// </summary>
        static void SimplePolicy(Tpm2 tpm)
        {
            Console.WriteLine("Simple Policy sample:");

            //
            // Check if policy commands are implemented by TPM. This list
            // could include all the other used commands as well.
            // This check here makes sense for policy commands, because
            // usually a policy has to be executed in full. If a command
            // out of the chain of policy commands is not implemented in the
            // TPM, the policy cannot be satisfied.
            // 
            var usedCommands = new[] {
                                        TpmCc.PolicyLocality,
                                        TpmCc.PolicyPCR
            };
            foreach (var commandCode in usedCommands)
            {
                if (!tpm.Helpers.IsImplemented(commandCode))
                {
                    Console.WriteLine("Cancel Simple Policy sample, because command {0} is not implemented by TPM.", commandCode);
                    return;
                }
            }

            //
            // First read the PCR values
            // 
            var pcrs = new uint[] { 1, 2, 3 };
            var sel = new PcrSelection(TpmAlgId.Sha, pcrs);

            PcrSelection[] selOut;
            Tpm2bDigest[] pcrValues;
            
            tpm.PcrRead(new[] { sel }, out selOut, out pcrValues);

            Console.WriteLine("PCR Selections:\n");
            foreach (PcrSelection s in selOut)
            {
                Console.WriteLine(s.ToString());
            }

            Console.WriteLine("PCR Values:\n");
            foreach (var v in pcrValues)
            {
                Console.WriteLine(v.ToString());
            }

            //
            // Save the current PCR values in a convenient data structure
            // 
            var expectedPcrVals = new PcrValueCollection(selOut, pcrValues);

            //
            // Tpm2Lib encapsulates a set of policy assertions as the PolicyTree class.  
            // 
            var policyTree = new PolicyTree(TpmAlgId.Sha256);

            //
            // Set the policy: Locality AND PolicyPcr. This form of CreatePOlicy
            // only creates a single chain. Note that all well-formed policy chains
            // must have leaf identifiers. Leaf identifiers are just strings that
            // are unique in a policy so that the framework can be told what
            // chain to evaluate.
            // 
            policyTree.Create(
                new PolicyAce[] 
                {
                    new TpmPolicyLocality(LocalityAttr.TpmLocZero),
                    new TpmPolicyPcr(expectedPcrVals),
                    "leaf"
                }
            );

            //
            // Ask Tpm2Lib for the expected policy-hash for this policy
            // 
            TpmHash expectedPolicyHash = policyTree.GetPolicyDigest();

            //
            // Create a sealed primary object with the policy-hash we just calculated
            // 
            var dataToSeal = new byte[] { 1, 2, 3, 4, 5, 4, 3, 2, 1 };
            TpmHandle primHandle = CreateSealedPrimaryObject(tpm, 
                                                             dataToSeal, 
                                                             null, 
                                                             expectedPolicyHash.HashData);
            //
            // Create an actual TPM policy session to evaluate the policy
            //
            AuthSession session = tpm.StartAuthSessionEx(TpmSe.Policy, TpmAlgId.Sha256);

            //
            // Run the policy on the TPM
            // 
            session.RunPolicy(tpm, policyTree, "leaf");

            //
            // Unseal the object
            //
            byte[] unsealedData = tpm[session].Unseal(primHandle);
            Console.WriteLine("Unsealed data: " + BitConverter.ToString(unsealedData));

            //
            // Change a PCR and make sure that the policy no longer works
            // 
            var nullAuth = new AuthValue();
            tpm[nullAuth].PcrEvent(TpmHandle.Pcr(3), new byte[] { 1, 2, 3 });
            tpm.PolicyRestart(session.Handle);

            //
            // Run the policy again - an error will be returned
            // 
            TpmRc policyError = session.RunPolicy(tpm, policyTree, null, true);

            //
            // And the session will be unusable
            // 
            unsealedData = tpm[session]._ExpectError(TpmRc.PolicyFail).Unseal(primHandle);

            //
            // Clean up
            // 
            tpm.FlushContext(session.Handle);
            tpm.FlushContext(primHandle);
        }
Example #47
0
        /// <summary>
        /// Create a sealed-object primary that can be accessed with the given policy. SHA256 is assumed.
        /// </summary>
        /// <param name="tpm"></param>
        /// <param name="dataToSeal"></param>
        /// <param name="authValue"></param>
        /// <param name="policy"></param>
        /// <returns></returns>
        private static TpmHandle CreateSealedPrimaryObject(Tpm2 tpm, byte[] dataToSeal, byte[] authValue, byte[] policy)
        {
            ObjectAttr attrs = ObjectAttr.FixedTPM | ObjectAttr.FixedParent;

            if (authValue != null)
            {
                attrs |= ObjectAttr.UserWithAuth;
            }

            byte[] policyVal = policy ?? new byte[0];
            var sealedInPublic = new TpmPublic(TpmAlgId.Sha256,
                                               attrs,
                                               policyVal,
                                               new KeyedhashParms(new NullSchemeKeyedhash()),
                                               new Tpm2bDigestKeyedhash());

            //
            // Envelope for sealed data and auth
            // 
            byte[] authVal = authValue ?? new byte[0];
            var sealedInSensitive = new SensitiveCreate(authVal, dataToSeal);

            TkCreation creationTicket;
            byte[] creationHashSealed;
            TpmPublic sealedPublic;
            CreationData sealedCreationData;

            //
            // 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();

            //
            // Ask the TPM to create a primary containing the "sealed" data
            // 
            TpmHandle primHandle = tpm[ownerAuth].CreatePrimary(TpmHandle.RhOwner,
                                                                sealedInSensitive,
                                                                sealedInPublic,
                                                                new byte[0],
                                                                new PcrSelection[0],
                                                                out sealedPublic,
                                                                out sealedCreationData,
                                                                out creationHashSealed,
                                                                out creationTicket);
            return primHandle;
        }
Example #48
0
        public static uint GetProperty(Tpm2 tpm, Pt prop)
        {
            ICapabilitiesUnion caps;
            tpm.GetCapability(Cap.TpmProperties, (uint)prop, 1, out caps);
            var props = (TaggedTpmPropertyArray)caps;
            TaggedProperty[] arr = props.tpmProperty;
            if (arr.Length != 1)
            {
                Globs.Throw("Unexpected return from GetCapability");
                if (arr.Length == 0)
                    return 0;
            }

            uint val = arr[0].value;
            return val;
        }
Example #49
0
        /// <summary>
        /// This sample demonstrates a policy containing ALL policy commands.  
        /// It also demonstrates serialization of the policy, and the use
        /// of callbacks to satisfy the conditions in a policy (e.g. knowledge
        /// of a private key, or the NV-index associated with a name.
        /// </summary>
        /// <param name="tpm">Reference to the TPM used.</param>
        static void SamplePolicySerializationAndCallbacks(Tpm2 tpm)
        {
            Console.WriteLine("Policy sample that serializes all policy commands.");

            //
            // Check if policy commands are implemented by TPM. This list
            // could include all the other used commands as well.
            // This check here makes sense for policy commands, because
            // usually a policy has to be executed in full. If a command
            // out of the chain of policy commands is not implemented in the
            // TPM, the policy cannot be satisfied.
            // 
            var usedCommands = new[] {
                                       TpmCc.PolicyPhysicalPresence,
                                       TpmCc.PolicySigned,
                                       TpmCc.PolicySecret,
                                       TpmCc.PolicyPCR,
                                       TpmCc.PolicyLocality,
                                       TpmCc.PolicyNV,
                                       TpmCc.PolicyCounterTimer,
                                       TpmCc.PolicyCommandCode,
                                       TpmCc.PolicyPassword,
                                       TpmCc.PolicyAuthorize,
                                       TpmCc.PolicyPhysicalPresence,
                                       TpmCc.PolicyCpHash,
                                       TpmCc.PolicyTicket,
                                       TpmCc.PolicyNameHash,
                                       TpmCc.PolicyCpHash,
                                       TpmCc.PolicyDuplicationSelect,
                                       TpmCc.PolicyAuthValue,
                                       TpmCc.PolicyNvWritten
            };
            foreach (var commandCode in usedCommands)
            {
                if (!tpm.Helpers.IsImplemented(commandCode))
                {
                    Console.WriteLine("Cancel Policy serialization and callback sample, because command {0} is not implemented by TPM.", commandCode);
                    return;
                }
            }

            //
            // 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();

            var pInit = new PolicyTree(TpmAlgId.Sha256);
            var p = new PolicyTree(TpmAlgId.Sha256);

            //
            // In the first part of this sample we establish keys, NV-slots, 
            // etc. that will be used in the policy.
            // 

            //
            // create a new RSA software signing key. We will use this for both 
            // TpmPolicySigned AND TpmPolicyAuthorize.
            // 
            var signKeyPublicTemplate = new TpmPublic(TpmAlgId.Sha256,
                                                      ObjectAttr.Sign | ObjectAttr.Restricted | ObjectAttr.FixedTPM,
                                                      new byte[0],
                                                      new RsaParms(new SymDefObject(),
                                                                   new SchemeRsassa(TpmAlgId.Sha256), 
                                                                   2048, 0),
                                                      new Tpm2bPublicKeyRsa());
            _publicSigningKey = new AsymCryptoSystem(signKeyPublicTemplate);

            //
            // Get an authorization ticket for TpmPolicyAuthorize. We will authorize
            // a policy-digest consisting of policyPhysPresense.
            // 
            var tempPolicy = new PolicyTree(TpmAlgId.Sha256);
            tempPolicy.Create(
                new PolicyAce[]
                {
                    new TpmPolicyPhysicalPresence(), 
                    "leaf"
                });

            TpmHash initPolicyHash = tempPolicy.GetPolicyDigest();
            var policyAuthRef = new byte[0];
            byte[] dataToSign = Globs.Concatenate(initPolicyHash.HashData, policyAuthRef);
            byte[] aHash = CryptoLib.HashData(TpmAlgId.Sha256, 
                                              Globs.Concatenate(initPolicyHash.HashData, policyAuthRef));

            //
            // Sign the simple policy just containing PolicyPhysPres so that 
            // we can change it to a new value with PolicyAuthorize.
            // 
            ISignatureUnion policyAuthSig = _publicSigningKey.Sign(dataToSign);

            //
            // Get a ticket verifying the signature.
            // 
            TpmHandle verifierHandle = tpm.LoadExternal(null, _publicSigningKey.GetPublicParms(), TpmHandle.RhOwner);
            tpm.VerifySignature(verifierHandle, aHash, policyAuthSig);
            tpm.FlushContext(verifierHandle);

            //
            // Get the value of PCR[1]
            // 
            var pcrs = new uint[] { 1 };
            var sel = new PcrSelection(TpmAlgId.Sha, pcrs);
            PcrSelection[] selOut;
            Tpm2bDigest[] pcrValues;
            tpm.PcrRead(new[] { sel }, out selOut, out pcrValues);

            //
            // Save the current PCR values in a convenient data structure
            // 
            var expectedPcrVals = new PcrValueCollection(selOut, pcrValues);

            //
            // Set up an NV slot
            // 
            TpmHandle nvHandle = TpmHandle.NV(3001);

            //
            // Clean anything that might have been there before
            // 
            tpm[ownerAuth]._AllowErrors().NvUndefineSpace(TpmHandle.RhOwner, nvHandle);

            AuthValue nvAuth = AuthValue.FromRandom(8);

            tpm[ownerAuth].NvDefineSpace(TpmHandle.RhOwner, nvAuth, new NvPublic(nvHandle, TpmAlgId.Sha1,
                                         NvAttr.TpmaNvAuthread | NvAttr.TpmaNvAuthwrite, new byte[0], 32));
            //
            // write some data
            // 
            var nvData = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7 };
            tpm[nvAuth].NvWrite(nvHandle, nvHandle, nvData, 0);
            byte[] nvName;
            tpm.NvReadPublic(nvHandle, out nvName);

            //
            // Install evaluation callback
            // Note: generally the callback will check that the parameters are
            // actions that it is willing to authorize. Those checks are omitted here.
            // 
            p.SetNvCallback((PolicyTree policyTree,
                             TpmPolicyNV ace,
                             out SessionBase authorizingSession,
                             out TpmHandle authorizedEntityHandle,
                             out TpmHandle nvHandleIs) =>
            {
                authorizedEntityHandle = nvHandle;
                nvHandleIs = nvHandle;
                authorizingSession = nvAuth;
            });

            //
            // counter-timer:  The policy will check that the reset-count
            // is the current value.
            // 
            int start, end;
            TimeInfo now = tpm.ReadClock();            
            Marshaller.GetFragmentInfo(now, "resetCount", out start, out end);
            byte[] operandB = Marshaller.GetTpmRepresentation(now.clockInfo.resetCount);

            //
            // Get a cpHash for the command we want to execute
            // 
            var cpHash = new TpmHash(TpmAlgId.Sha256);
            tpm._GetCpHash(cpHash).HierarchyChangeAuth(TpmHandle.RhOwner, ownerAuth);

            p.SetSignerCallback(SignerCallback);

            //
            // PolicySecret tests knowledge of ownerAuth. Note that the callback 
            // will generally check that it is prepared to authorize what it is 
            // being asked to authorize. Those checks are omitted here (we just
            // provide a PWAP session containing ownerAuth.
            // 
            p.SetPolicySecretCallback((PolicyTree policyTree,
                                       TpmPolicySecret ace,
                                       out SessionBase authorizingSession,
                                       out TpmHandle authorizedEntityHandle,
                                       out bool flushAuthEntity) =>
            {
                authorizingSession = ownerAuth;
                authorizedEntityHandle = TpmHandle.RhOwner;
                flushAuthEntity = false;
            });

            //
            // If the policy contains a TpmPolicyAction then print out the 
            // action string on the console.  
            // 
            p.SetPolicyActionCallback((PolicyTree policy, TpmPolicyAction ace)
                                      => Console.WriteLine(ace.Action));

            var policyRef = new byte[] { 1, 2, 3, 4 };

            //
            // Ticket expiration times have to be negative.
            // Positive expiration times do not generate a ticket.
            // 
            _expectedExpirationTime = -60;

            //
            // A normalized policy is an array of policy-chains written as 
            // arrays. Here "most" of the policy-ACEs are in the first chain, but some 
            // ACEs cannot co-exist, and some need a ticket from a prior evaluation.
            // 
            pInit.CreateNormalizedPolicy(
                new[] 
                {
                    new PolicyAce[]
                    {
                        new TpmPolicySigned(_publicSigningKey.GetPublicParms().GetName(),
                                                                                // Newly created PubKey
                                            true,                               // Nonce in signed data
                                            _expectedExpirationTime,            // expirationTime
                                            new byte[0],                        // cpHash
                                            policyRef)                          // policyRef
                        {NodeId = "Signing Key 1"},                             // Distinguishing name

                        //
                        // Include owner-auth
                        // 
                        new TpmPolicySecret(TpmHandle.RhOwner.GetName(), true,
                                            new byte[0], new byte[] {1, 2, 3}, 0),

                        //
                        // Include PCR-values read earlier
                        // 
                        new TpmPolicyPcr(expectedPcrVals), 

                        //
                        // Command must be issued at locality two
                        // 
                        new TpmPolicyLocality(LocalityAttr.TpmLocTwo), 

                        //
                        // NV-data we set earlier must be present
                        // 
                        new TpmPolicyNV(nvName, nvData, 0, Eo.Eq), 

                        //
                        // This is a "dummy ACE" that is not executed on the TPM but
                        // a callback will be invoked at when the policy is executed.
                        // One use case for this is to increment a counter between two
                        // PolicyNV counter-checks.
                        // 
                        new TpmPolicyAction("Output of TpmPolicyAction when executed."),

                        //
                        // Boot-count must be what we read earlier
                        // 
                        new TpmPolicyCounterTimer(operandB, (ushort) start, Eo.Eq),

                        //
                        // Only authorize HierarchyChangeAuth
                        // 
                        new TpmPolicyCommand(TpmCc.HierarchyChangeAuth),

                        //
                        // Include password
                        // 
                        new TpmPolicyPassword(), 

                        //
                        // Authorize a change from PolicyPP (last ACE below)
                        // 
                        new TpmPolicyAuthorize(initPolicyHash.HashData, 
                                               policyAuthRef, 
                                               _publicSigningKey.GetPublicParms(), 
                                               TpmAlgId.Sha256, 
                                               policyAuthSig),
                        //
                        // Demand that the command be executed with PP asserted
                        // 
                        new TpmPolicyPhysicalPresence(), 

                        //
                        // Name for this branch
                        //
                        "branch_1"
                    },

                    new PolicyAce[]
                    {
                        //
                        // Bind to command/parameters
                        //
                        new TpmPolicyCpHash(cpHash),   

                        //
                        // Name for this branch
                        //
                        "branch_2"
                    },

                    new PolicyAce[]
                    {
                        new TpmPolicyTicket(_publicSigningKey.GetPublicParms(),
                                            policyRef,
                                            TpmSt.AuthSigned)
                        //
                        // Distinguishing name for this node
                        //
                        {NodeId = "PolicyTicket"},     

                        //
                        // Name for this branch
                        //
                        "branch_3"
                    },

                    //
                    // TODO: These ACEs are not evaluated yet in this sample
                    //
                    new PolicyAce[]
                    {
                        new TpmPolicyNameHash(),
                        new TpmPolicyCpHash(cpHash),
                        new TpmPolicyDuplicationSelect(new byte[0], new byte[0], true), 
                        new TpmPolicyAuthValue(), // Include entity authValue in HMAC
                        new TpmPolicyNvWritten(),
                        "branch_4"
                    }
                }
            );

            TpmHash policyHash = pInit.GetPolicyDigest();

            //
            // Check that we can serialize and deserialize the policy
            // 
            const string fileName = @".\test1.xml";
            pInit.SerializeToFile("Sample Policy",PolicySerializationFormat.Xml, fileName);
            p.DeserializeFromFile(PolicySerializationFormat.Xml, fileName);
            
            //
            // And check that the policy hash is the same
            // 
            TpmHash deserializedHash = p.GetPolicyDigest();
            if (policyHash != deserializedHash)
            {
                throw new Exception("Serialization error");
            }

            //
            // Execute the policy on the TPM. Start with "branch_1".
            // 
            AuthSession s0 = tpm.StartAuthSessionEx(TpmSe.Policy, TpmAlgId.Sha256);
            s0.RunPolicy(tpm, p, "branch_1");

            //
            // Check that the executed policy has the correct digest
            // 
            byte[] actualPolicyDigest = tpm.PolicyGetDigest(s0.Handle);
            if (policyHash != actualPolicyDigest)
            {
                throw new Exception("Policy Evaluation error");
            }

            //
            // Set a command to use the policy
            // 
            tpm[ownerAuth].SetPrimaryPolicy(TpmHandle.RhOwner, policyHash.HashData, TpmAlgId.Sha256);

            //
            // And then execute the command
            // 
            tpm._AssertPhysicalPresence(true);
            tpm._SetLocality(LocalityAttr.TpmLocTwo);
            tpm[s0].HierarchyChangeAuth(TpmHandle.RhOwner, ownerAuth);
            tpm._SetLocality(LocalityAttr.TpmLocZero);
            tpm._AssertPhysicalPresence(false);
            tpm.FlushContext(s0.Handle);

            //
            // Next, "branch_2".
            // 
            s0 = tpm.StartAuthSessionEx(TpmSe.Policy, TpmAlgId.Sha256);
            s0.RunPolicy(tpm, p, "branch_2");
            tpm[s0].HierarchyChangeAuth(TpmHandle.RhOwner, ownerAuth);
            tpm.FlushContext(s0.Handle);

            //
            // Now "branch_3" - ticket. Copy parms out of the ticket/ACE returned
            // from TpmPolicySinged above.
            // 
            var sigAce = p.GetAce<TpmPolicySigned>("Signing Key 1");
            TkAuth signedTicket = p.GetTicket("Signing Key 1");

            var tickAce = p.GetAce<TpmPolicyTicket>("PolicyTicket");
            tickAce.CpHash = sigAce.CpHash;
            tickAce.PolicyRef = sigAce.PolicyRef;
            tickAce.ExpirationTime = sigAce.GetTimeout();
            tickAce.SetTicket(signedTicket);

            s0 = tpm.StartAuthSessionEx(TpmSe.Policy, TpmAlgId.Sha256);
            s0.RunPolicy(tpm, p, "branch_3");
            tpm[s0].HierarchyChangeAuth(TpmHandle.RhOwner, ownerAuth);
            tpm.FlushContext(s0.Handle);

            Console.WriteLine("Finished SamplePolicySerializationAndCallbacks.");
        }
Example #50
0
        /// <summary>
        /// Get the date of the specification from which the TPM was built.
        /// </summary>
        /// <param name="manufacturer"></param>
        /// <param name="year"></param>
        /// <param name="dayOfYear"></param>
        /// <param name="tpm"></param>
        public static void GetTpmInfo(Tpm2 tpm, out string manufacturer, out uint year, out uint dayOfYear)
        {
            // ReSharper disable once RedundantAssignment
            manufacturer = "";
            year = GetProperty(tpm, Pt.Year);
            dayOfYear = GetProperty(tpm, Pt.DayOfYear);

            uint manX = GetProperty(tpm, Pt.Manufacturer);
            var arr = Marshaller.GetTpmRepresentation(manX);
            manufacturer = (new System.Text.UTF8Encoding()).GetString(arr, 0, arr.Length);
        }
Example #51
0
        /// <summary>
        /// Some policies can be evaluated solely from public parts of the policy.
        /// Others need a private keyholder to sign some data. Tpm2Lib provides a
        /// callback facility for these cases. In this sample the callback 
        /// signs some data using a software key. But the callback might also 
        /// ask for a smartcard to sign a challenge, etc.
        /// </summary>
        /// <param name="tpm">reference to the TPM2 object to use.</param>
        static void PolicyEvaluationWithCallback(Tpm2 tpm)
        {
            Console.WriteLine("Policy evaluation with callback sample.");

            //
            // Check if policy commands are implemented by TPM. This list
            // could include all the other used commands as well.
            // This check here makes sense for policy commands, because
            // usually a policy has to be executed in full. If a command
            // out of the chain of policy commands is not implemented in the
            // TPM, the policy cannot be satisfied.
            // 
            var usedCommands = new[] {
                                        TpmCc.PolicySigned,
                                        TpmCc.PolicyGetDigest
            };
            foreach (var commandCode in usedCommands)
            {
                if (!tpm.Helpers.IsImplemented(commandCode))
                {
                    Console.WriteLine("Cancel Policy evaluation callback sample, because command {0} is not implemented by TPM.", commandCode);
                    return;
                }
            }

            //
            // Template for a software signing key
            // 
            var signKeyPublicTemplate = new TpmPublic(TpmAlgId.Sha256,
                                                      ObjectAttr.Sign | ObjectAttr.Restricted,
                                                      new byte[0],
                                                      new RsaParms(SymDefObject.NullObject(),
                                                                   new SchemeRsassa(TpmAlgId.Sha1),
                                                                   2048, 0),
                                                      new Tpm2bPublicKeyRsa());
            //
            // Create a new random key
            // 
            _publicSigningKey = new AsymCryptoSystem(signKeyPublicTemplate);

            //
            // Create a policy containing a TpmPolicySigned referring to the new 
            // software signing key.
            // 
            _expectedExpirationTime = 60;
            var policy = new PolicyTree(TpmAlgId.Sha256);

            policy.Create(
                new PolicyAce[]
                {
                    new TpmPolicySigned(_publicSigningKey.GetPublicParms().GetName(), 
                                                                            // Newly created PubKey
                                        true,                               // nonceTpm required, expiration time is given
                                        _expectedExpirationTime,            // expirationTime for policy
                                        new byte[0],                        // cpHash
                                        new byte[] {1, 2, 3, 4})            // policyRef
                                        {NodeId = "Signing Key 1"},         // Distinguishing name
                                        new TpmPolicyChainId("leaf")        // Signed data
                });

            //
            // Compute the expected hash for the policy session. This hash would be
            // used in the object associated with the policy to confirm that the 
            // policy is actually fulfilled.
            // 
            TpmHash expectedHash = policy.GetPolicyDigest();

            //
            // The use of the object associated with the policy has to evaluate the
            // policy. In order to process TpmPolicySigned the caller will have to 
            // sign a data structure challenge from the TPM. Here we install a 
            // callback that will sign the challenge from the TPM. 
            // 
            policy.SetSignerCallback(SignerCallback);

            //
            // Evaluate the policy. Tpm2Lib will traverse the policy tree from leaf to 
            // root (in this case just TpmPolicySigned) and will call the signer callback
            // to get a properly-formed challenge signed.
            // 
            AuthSession authSession = tpm.StartAuthSessionEx(TpmSe.Policy, TpmAlgId.Sha256);
            authSession.RunPolicy(tpm, policy, "leaf");

            //
            // And check that the TPM policy hash is what we expect
            // 
            byte[] actualHash = tpm.PolicyGetDigest(authSession.Handle);

            if (expectedHash != actualHash)
            {
                throw new Exception("Policy evaluation error");
            }

            Console.WriteLine("TpmPolicySignature evaluated.");

            //
            // Clean up
            // 
            tpm.FlushContext(authSession.Handle);
        }
Example #52
0
 internal abstract TpmRc Execute(Tpm2 tpm, AuthSession sess, PolicyTree policy);
Example #53
0
        /// <summary>
        /// Demonstrate use of NV counters.
        /// </summary>
        /// <param name="tpm">Reference to the TPM object.</param>
        static 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.
            //
            var ownerAuth = new AuthValue();
            TpmHandle nvHandle = TpmHandle.NV(3001);

            //
            // Clean up any slot that was left over from an earlier run
            // 
            tpm[ownerAuth]._AllowErrors().NvUndefineSpace(TpmHandle.RhOwner, nvHandle);

            //
            // Scenario 2 - A NV-counter
            // 
            AuthValue nvAuth = AuthValue.FromRandom(8);
            tpm[ownerAuth].NvDefineSpace(TpmHandle.RhOwner, nvAuth,
                                         new NvPublic(nvHandle, TpmAlgId.Sha1,
                                                      NvAttr.Counter  | 
                                                      NvAttr.Authread | 
                                                      NvAttr.Authwrite,
                                                      new byte[0], 8));
            //
            // Must write before we can read
            // 
            tpm[nvAuth].NvIncrement(nvHandle, nvHandle);

            //
            // Read the current value
            // 
            byte[] nvRead = tpm[nvAuth].NvRead(nvHandle, nvHandle, 8, 0);
            var initVal = Marshaller.FromTpmRepresentation<ulong>(nvRead);

            //
            // Increment
            // 
            tpm[nvAuth].NvIncrement(nvHandle, nvHandle);

            //
            // Read again and see if the answer is what we expect
            // 
            nvRead = tpm[nvAuth].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);

            //
            // Clean up
            // 
            tpm[ownerAuth].NvUndefineSpace(TpmHandle.RhOwner, nvHandle);
        }
Example #54
0
 internal override TpmRc Execute(Tpm2 tpm, AuthSession sess, PolicyTree policy)
 {
     Tpm2bDigest[] branchList = GetPolicyHashArray(policy.PolicyHash.HashAlg);
     tpm.PolicyOR(sess, branchList);
     return(tpm._GetLastResponseCode());
 }
Example #55
0
        /// <summary>
        /// Dispatch a command to the underlying TPM. This method implements all
        /// significant functionality. It examines the command stream and performs
        /// (approximately) the following actions:
        /// 1) If the command references a handle (session or transient object), then
        ///     TBS makes sure that the entity  is loaded. If it is, then the handle is
        ///     "translated" to the underlying TPM handle. If it is not, then TBS checks
        ///     to see if it has a saved context for the entity, and if so, loads it.
        /// 2) If the command will fill a slot, then TBS ensures that a slot is available.
        ///     It does this by ContextSaving the LRU entity of the proper type (that is
        ///     not used in this command).
        /// </summary>
        /// <param name="caller"></param>
        /// <param name="active"></param>
        /// <param name="inBuf"></param>
        /// <param name="outBuf"></param>
        /// <exception cref="Exception"></exception>
        internal void DispatchCommand(TbsContext caller, CommandModifier active, byte[] inBuf, out byte[] outBuf)
        {
            lock (this)
            {
                CommandNumber++;
                // ReSharper disable once CompareOfFloatsByEqualityOperator
                if (StateSaveProbability != 0.0)
                {
                    // S3 debug support
                    DebugStateSave();
                    LastStateSaveCommandNumber = CommandNumber;
                }

                CommandHeader commandHeader;
                TpmHandle[]   inHandles;
                SessionIn[]   inSessions;
                byte[]        commandParmsNoHandles;
                bool          legalCommand = CommandProcessor.CrackCommand(inBuf,
                                                                           out commandHeader, out inHandles, out inSessions, out commandParmsNoHandles);

                if (!legalCommand)
                {
                    // Is a diagnostics command.  Pass through to TPM (a real RM would refuse).
                    TpmDevice.DispatchCommand(active, inBuf, out outBuf);
                    return;
                }

                TpmCc cc = commandHeader.CommandCode;

                // Lookup command
                CommandInfo command = Tpm2.CommandInfoFromCommandCode(cc);
                if (command == null)
                {
                    throw new Exception("Unrecognized command");
                }

                if (cc == TpmCc.ContextLoad || cc == TpmCc.ContextSave)
                {
                    Debug.WriteLine("ContextLoad and ContextSave are not supported in this build");
                    outBuf = Marshaller.GetTpmRepresentation(new Object[] {
                        TpmSt.NoSessions,
                        (uint)10,
                        TpmRc.NotUsed
                    });
                }

                // Look up referenced objects and sessions
                ObjectContext[] neededObjects  = GetReferencedObjects(caller, inHandles);
                ObjectContext[] neededSessions = GetSessions(caller, inSessions);
                ObjectContext[] neededEntities =
                    neededObjects != null
                            ? neededSessions != null
                                ? neededObjects.Concat(neededSessions).ToArray()
                                : neededObjects
                            : neededSessions;

#if false
                // LibTester may intentionally use invalid handles, therefore it always
                // work in the passthru mode (all correctness checks by TSS infra suppressed)
                if (!Tpm2._TssBehavior.Passthrough &&
                    (neededObjects == null || neededSessions == null))
#endif
                if (neededObjects == null || neededSessions == null)
                {
                    // One or more of the handles was not registered for the context
                    byte[] ret = FormatError(TpmRc.Handle);
                    outBuf = ret;
                    return;
                }

                // Load referenced objects and sessions (free slots if needed)
                // It's important to load all object and session handles in a single call
                // to LoadEntities(), as for some commands (e.g. GetSessionAuditDigest)
                // the objects array may contain session handles. In this case the session
                // handles loaded by the invocation of LoadEntities for neededObjects
                // may be evicted again during the subsequent call for neededSessions.
                var expectedResponses = Tpm._GetExpectedResponses();
                if (!LoadEntities(neededEntities))
                {
                    throw new Exception("Failed to make space for objects or sessions");
                }
                else
                {
                    // At this point everything referenced should be loaded, and
                    // there will be a free slot if needed so we can translate
                    // the input handles to the underlying handles
                    ReplaceHandlesIn(inHandles, inSessions, neededObjects, neededSessions);
                }

                // Re-create the command using translated object and session handles
                byte[] commandBuf = CommandProcessor.CreateCommand(commandHeader.CommandCode,
                                                                   inHandles, inSessions, commandParmsNoHandles);
                if (!Tpm2._TssBehavior.Passthrough)
                {
                    Debug.Assert(commandBuf.Length == inBuf.Length);
                }

                byte[] responseBuf;

                // TODO: Virtualize TPM2_GetCapability() for handle enumeration.

                //
                // Execute command on underlying TPM device.
                // If we get an ObjectMemory or SessionMemory error we try to make more space and try again
                // Note: If the TPM device throws an error above we let it propagate out.  There should be no side
                // effects on TPM state that the TBS cares about.
                //
                ulong firstCtxSeqNum = 0;
                while (true)
                {
                    Tpm._ExpectResponses(expectedResponses);
                    TpmDevice.DispatchCommand(active, commandBuf, out responseBuf);

                    TpmRc res = GetResultCode(responseBuf);
                    if (res == TpmRc.Success ||
                        expectedResponses != null && expectedResponses.Contains(res))
                    {
                        break;
                    }

                    if (res == TpmRc.ContextGap)
                    {
                        ulong seqNum = ShortenSessionContextGap(firstCtxSeqNum);
                        if (seqNum == 0)
                        {
                            break;  // Failed to handle CONTEXT_GAP error
                        }
                        if (firstCtxSeqNum == 0)
                        {
                            firstCtxSeqNum = seqNum;
                        }

                        //if (firstCtxSeqNum != 0)
                        //    Console.WriteLine("DispatchCommand: CONTEXT_GAP handled");
                        continue;
                    }

                    var slotType = SlotType.NoSlot;
                    if (res == TpmRc.ObjectHandles || res == TpmRc.ObjectMemory)
                    {
                        slotType = SlotType.ObjectSlot;
                    }
                    else if (res == TpmRc.SessionHandles || res == TpmRc.SessionMemory)
                    {
                        slotType = SlotType.SessionSlot;
                    }
                    else
                    {
                        // Command failure not related to resources
                        break;
                    }
                    if (!MakeSpace(slotType, neededEntities))
                    {
                        // Failed to make an object slot in the TPM
                        responseBuf = TpmErrorHelpers.BuildErrorResponseBuffer(TpmRc.Memory);
                        break;
                    }
                }

                // Parse the response from the TPM
                TpmSt        responseTag;
                uint         responseParamSize;
                TpmRc        resultCode;
                TpmHandle[]  responseHandles;
                SessionOut[] responseSessions;
                byte[]       responseParmsNoHandles, responseParmsWithHandles;

                CommandProcessor.SplitResponse(responseBuf,
                                               command.HandleCountOut,
                                               out responseTag,
                                               out responseParamSize,
                                               out resultCode,
                                               out responseHandles,
                                               out responseSessions,
                                               out responseParmsNoHandles,
                                               out responseParmsWithHandles);

                // In case of an error there is no impact on the loaded sessions, but
                // we update the LRU values because the user will likely try again.
                if (resultCode != TpmRc.Success)
                {
                    outBuf = responseBuf;
                    UpdateLastUseCount(new[] { neededObjects, neededSessions });
                    return;
                }

                // Update TBS database with any newly created TPM objects
                ProcessUpdatedTpmState(caller, command, responseHandles, neededObjects);

                // And if there were any newly created objects use the new DB entries
                // to translate the handles
                ReplaceHandlesOut(responseHandles);
                outBuf = CommandProcessor.CreateResponse(resultCode, responseHandles,
                                                         responseSessions, responseParmsNoHandles);

                Debug.Assert(outBuf.Length == responseBuf.Length);
            } // lock(this)
        }
Example #56
0
 internal override TpmRc Execute(Tpm2 tpm, AuthSession sess, PolicyTree policy)
 {
     tpm.PolicyPCR(sess, Pcrs.GetSelectionHash(policy.PolicyHash),
                   Pcrs.GetPcrSelectionArray());
     return(tpm._GetLastResponseCode());
 }
Example #57
0
 public static byte[] GetPcrProperty(Tpm2 tpm, PtPcr prop)
 {
     ICapabilitiesUnion caps;
     tpm.GetCapability(Cap.PcrProperties, (uint)prop, 1, out caps);
     TaggedPcrSelect[] props = (caps as TaggedPcrPropertyArray).pcrProperty;
     if (props.Length == 0)
     {
         return null;
     }
     if (props.Length != 1)
     {
         Globs.Throw("Unexpected return from GetCapability");
     }
     return props[0].pcrSelect;
 }
Example #58
0
        /// <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();
        }
Example #59
0
        /// <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();
        }
Example #60
0
        /// <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();
        }