A PolicyTree contains machinery for creating, executing and persisting TPM policy expression.
Beispiel #1
0
 internal override TpmRc Execute(Tpm2 tpm, AuthSession sess, PolicyTree policy)
 {
     tpm.PolicyPassword(sess);
     sess.SessIncludesAuth = true;
     sess.PlaintextAuth    = true;
     return(tpm._GetLastResponseCode());
 }
Beispiel #2
0
        internal static PolicyAce FromArrayRepresentation(PolicyAce[] arr, PolicyTree policy)
        {
            PolicyAce root     = null;
            PolicyAce current  = null;
            PolicyAce previous = null;

            // Makes a doubly linked list from an array
            foreach (PolicyAce a in arr)
            {
                // All ACEs have an associated policy tree
                a.AssociatedPolicy = policy;
                // we need a link to previous
                if (previous != null)
                {
                    a.PreviousAce = previous;
                }

                // previous needs a link to us
                if (current != null)
                {
                    current.NextAce = a;
                }

                current = a;
                if (root == null)
                {
                    root = current;
                }
                previous = a;
            }
            return(root);
        }
Beispiel #3
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());
        }
Beispiel #4
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);
        }
Beispiel #5
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());
        }
Beispiel #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());
 }
Beispiel #7
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());
        }
Beispiel #8
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);
        }
Beispiel #9
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);
        }
Beispiel #10
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());
        }
Beispiel #11
0
 internal override TpmRc Execute(Tpm2 tpm, AuthSession authSession, PolicyTree policy)
 {
     tpm.PolicyAuthorizeNV(AuthHandle, NvIndex, authSession);
     return tpm._GetLastResponseCode();
 }
Beispiel #12
0
 // ReSharper disable once InconsistentNaming
 internal override TpmRc Execute(Tpm2 tpm, AuthSession authSession, PolicyTree policy)
 {
     return TpmRc.Success;
 }
Beispiel #13
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);
        }
Beispiel #14
0
        // ReSharper disable once InconsistentNaming
        internal override TpmRc Execute(Tpm2 tpm, AuthSession authSession, PolicyTree policy)
        {
            byte[] dataToSign = Globs.Concatenate(PolicyToReplace, PolicyRef);
            byte[] aHash = CryptoLib.HashData(SigningHash, dataToSign);

            TpmHandle verifierHandle = tpm.LoadExternal(null, SigningKey, TpmRh.Owner);
            if (policy.AllowErrorsInPolicyEval)
            {
                tpm._AllowErrors();
            }

            // todo - fix the serialization so that we can persist the interface
            ISignatureUnion theSig = null;
            if(null!= (Object) Sig1)
            {
                theSig = Sig1;
            }
            if (null != (Object)Sig2)
            {
                theSig = Sig2;
            }

            if (theSig != null)
            {
                Ticket = tpm.VerifySignature(verifierHandle, aHash, theSig);
                TpmRc intermediateError = tpm._GetLastResponseCode();
                if (intermediateError != TpmRc.Success)
                {
                    tpm.FlushContext(verifierHandle);
                    return intermediateError;
                }
            }
            else
            {
                // create a dummy ticket = e.g. for a trial session
                Ticket = new TkVerified(TpmRh.Owner, new byte[0]);
            }
            tpm.FlushContext(verifierHandle);


            byte[] keySign = SigningKey.GetName();
            TpmHandle policySession = authSession;
            if (TheParamsCallback != null)
            {
                TheParamsCallback(tpm, ref policySession, ref PolicyToReplace, ref PolicyRef, keySign, ref Ticket);
            }
            if (policy.AllowErrorsInPolicyEval)
            {
                tpm._AllowErrors();
            }
            tpm.PolicyAuthorize(policySession, PolicyToReplace, PolicyRef, keySign, Ticket);

            return tpm._GetLastResponseCode();
        }
Beispiel #15
0
 // ReSharper disable once InconsistentNaming
 internal override TpmRc Execute(Tpm2 tpm, AuthSession authSession, PolicyTree policy)
 {
     policy.ExecutePolicyActionCallback(this);
     return TpmRc.Success;
 }
Beispiel #16
0
 // ReSharper disable once InconsistentNaming
 internal override TpmRc Execute(Tpm2 tpm, AuthSession authSession, PolicyTree policy)
 {
     Globs.Throw("Do not include PolicyRestart in running policies");
     return TpmRc.Policy;
 }
Beispiel #17
0
        // ReSharper disable once InconsistentNaming
        internal override TpmRc Execute(Tpm2 tpm, AuthSession authSession, 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, authSession,
                                     OperandB, Offset, Operation);
                res = tpm._GetLastResponseCode();

                if (!(nvAuth is Pwap))
                {
                    tpm.FlushContext(nvAuth);
                }
            }
            else
            {
                tpm[NvAccessAuth].PolicyNV(AuthorizationHandle, NvIndex, authSession,
                    OperandB, Offset, Operation);
                res = tpm._GetLastResponseCode();
            }
            return res;
        }
Beispiel #18
0
 // ReSharper disable once InconsistentNaming
 internal override TpmRc Execute(Tpm2 tpm, AuthSession authSession, PolicyTree policy)
 {
     tpm.PolicyLocality(authSession, AllowedLocality);
     return tpm._GetLastResponseCode();
 }
Beispiel #19
0
 // ReSharper disable once InconsistentNaming
 internal override TpmRc Execute(Tpm2 tpm, AuthSession authSession, PolicyTree policy)
 {
     tpm.PolicyNameHash(authSession, NameHash);
     return tpm._GetLastResponseCode();
 }
Beispiel #20
0
 // ReSharper disable once InconsistentNaming
 internal override TpmRc Execute(Tpm2 tpm, AuthSession policySession, PolicyTree policy)
 {
     tpm.PolicyCounterTimer(policySession, OperandB, Offset, Operation);
     return tpm._GetLastResponseCode();
 }
Beispiel #21
0
 // ReSharper disable once InconsistentNaming
 internal override TpmRc Execute(Tpm2 tpm, AuthSession policySession, PolicyTree policy)
 {
     tpm.PolicyPCR(policySession, Pcrs.GetSelectionHash(policy.PolicyHash.HashAlg), Pcrs.GetPcrSelectionArray());
     return tpm._GetLastResponseCode();
 }
Beispiel #22
0
 internal override TpmRc Execute(Tpm2 tpm, AuthSession sess, PolicyTree policy)
 {
     policy.ExecutePolicyActionCallback(this);
     return(TpmRc.Success);
 }
Beispiel #23
0
 // ReSharper disable once InconsistentNaming
 internal override TpmRc Execute(Tpm2 tpm, AuthSession authSession, PolicyTree policy)
 {
     Tpm2bDigest[] branchList = GetPolicyHashArray(policy.PolicyHash.HashAlg);
     tpm.PolicyOR(authSession, branchList);
     return tpm._GetLastResponseCode();
 }
Beispiel #24
0
 // ReSharper disable once InconsistentNaming
 internal override TpmRc Execute(Tpm2 tpm, AuthSession authSession, PolicyTree policy)
 {
     tpm.PolicyPassword(authSession);
     authSession.SessIncludesAuth = true;
     authSession.PlaintextAuth = true;
     return tpm._GetLastResponseCode();
 }
Beispiel #25
0
 // ReSharper disable once InconsistentNaming
 internal override TpmRc Execute(Tpm2 tpm, AuthSession authSession, PolicyTree policy)
 {
     tpm.PolicyPhysicalPresence(authSession);
     return tpm._GetLastResponseCode();
 }
Beispiel #26
0
        // ReSharper disable once InconsistentNaming
        internal override TpmRc Execute(Tpm2 tpm, AuthSession authSession, PolicyTree policy)
        {
            byte[] nonceTpm = UseNonceTpm ? Globs.CopyData(authSession.NonceTpm) : new byte[0];

            var dataToSign = new Marshaller();
            dataToSign.Put(nonceTpm, "");
            ISignatureUnion signature;
            // If the library has been given a signing key we can do the challenge here (else we need to call out)
            TpmHandle verificationKey;
            if (SigningKey != null)
            {
                dataToSign.Put(ExpirationTime, "");
                dataToSign.Put(CpHash, "");
                dataToSign.Put(PolicyRef, "");
                // Just ask the key to sign the challenge
                signature = SigningKey.Sign(dataToSign.GetBytes());
                verificationKey = tpm.LoadExternal(null, SigningKeyPub, TpmRh.Owner);
            }
            else
            {
                TpmPublic verifier;
                signature = AssociatedPolicy.ExecuteSignerCallback(this, nonceTpm, out verifier);
                verificationKey = tpm.LoadExternal(null, verifier, TpmRh.Owner);
            }
            TkAuth policyTicket;

            Timeout = tpm.PolicySigned(verificationKey,
                                       authSession,
                                       nonceTpm,
                                       CpHash,
                                       PolicyRef,
                                       ExpirationTime,
                                       signature,
                                       out policyTicket);

            TpmRc responseCode = tpm._GetLastResponseCode();
            // Save the policyTicket in case it is needed later
            PolicyTicket = policyTicket;
            tpm.FlushContext(verificationKey);
            return responseCode;
        }
Beispiel #27
0
 /// <summary>
 /// This callback function provides authorization in the form of an HMAC session
 /// </summary>
 static public void PolicySecretCallback2(
     PolicyTree policyTree,
     TpmPolicySecret ace,
     out SessionBase authorizingSession,
     out TpmHandle authorizedEntityHandle,
     out bool flushAuthEntity)
 {
     AuthSession s0 = _sharedTpm.StartAuthSessionEx(TpmSe.Hmac, TpmAlgId.Sha1);
     authorizingSession = s0;
     authorizedEntityHandle = _publicSealedObjectHandle;
     flushAuthEntity = true;
 }
Beispiel #28
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;
        }
Beispiel #29
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.");
        }
Beispiel #30
0
 internal TpmPolicy(PolicyTree policy)
 {
     AssociatedPolicy = policy;
     PolicyRoot = policy.GetPolicyRoot();
     PolicyHash = policy.GetPolicyDigest();
 }
Beispiel #31
0
 internal TpmPolicy(PolicyTree policy)
 {
     AssociatedPolicy = policy;
     PolicyRoot       = policy.GetPolicyRoot();
     PolicyHash       = policy.GetPolicyDigest();
 }
Beispiel #32
0
 internal abstract TpmRc Execute(Tpm2 tpm, AuthSession sess, PolicyTree policy);
Beispiel #33
0
 // ReSharper disable once InconsistentNaming
 internal override TpmRc Execute(Tpm2 tpm, AuthSession authSession, PolicyTree policy)
 {
     byte includeName = IncludeObjectNameInPolicyHash ? (byte)1 : (byte)0;
     tpm.PolicyDuplicationSelect(authSession, NameOfObject, NameOfNewParent, includeName);
     return tpm._GetLastResponseCode();
 }
Beispiel #34
0
 internal override TpmRc Execute(Tpm2 tpm, AuthSession sess, PolicyTree policy)
 {
     tpm.PolicyPCR(sess, Pcrs.GetSelectionHash(policy.PolicyHash),
                   Pcrs.GetPcrSelectionArray());
     return(tpm._GetLastResponseCode());
 }
Beispiel #35
0
 internal override TpmRc Execute(Tpm2 tpm, AuthSession sess, PolicyTree policy)
 {
     tpm.PolicyAuthorizeNV(AuthHandle, NvIndex, sess);
     return(tpm._GetLastResponseCode());
 }
Beispiel #36
0
 internal override TpmRc Execute(Tpm2 tpm, AuthSession sess, PolicyTree policy)
 {
     tpm.PolicyNameHash(sess, NameHash);
     return(tpm._GetLastResponseCode());
 }
Beispiel #37
0
 internal override TpmRc Execute(Tpm2 tpm, AuthSession sess, PolicyTree policy)
 {
     return(TpmRc.Success);
 }
Beispiel #38
0
 // ReSharper disable once InconsistentNaming
 internal override TpmRc Execute(Tpm2 tpm, AuthSession authSession, PolicyTree policy)
 {
     byte writtenName = IsNvIndexRequiredToHaveBeenWritten ? (byte)1 : (byte)0;
     tpm.PolicyNvWritten(authSession, writtenName);
     return tpm._GetLastResponseCode();
 }
Beispiel #39
0
        internal static PolicyAce FromArrayRepresentation(PolicyAce[] arr, PolicyTree policy)
        {
            PolicyAce root = null;
            PolicyAce current = null;
            PolicyAce previous = null;
            // Makes a doubly linked list from an array
            foreach (PolicyAce a in arr)
            {
                // All ACEs have an associated policy tree
                a.AssociatedPolicy = policy;
                // we need a link to previous
                if (previous != null)
                {
                    a.PreviousAce = previous;
                }
                
                // previous needs a link to us
                if (current != null)
                {
                    current.NextAce = a;
                }

                current = a;
                if (root == null)
                {
                    root = current;
                }
                previous = a;
            }
            return root;
        }
Beispiel #40
0
 // ReSharper disable once InconsistentNaming
 internal abstract TpmRc Execute(Tpm2 tpm, AuthSession authSession, PolicyTree policy);
Beispiel #41
0
 internal override TpmRc Execute(Tpm2 tpm, AuthSession sess, PolicyTree policy)
 {
     Tpm2bDigest[] branchList = GetPolicyHashArray(policy.PolicyHash.HashAlg);
     tpm.PolicyOR(sess, branchList);
     return(tpm._GetLastResponseCode());
 }
Beispiel #42
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);
        }
Beispiel #43
0
 internal override TpmRc Execute(Tpm2 tpm, AuthSession sess, PolicyTree policy)
 {
     tpm.PolicyCounterTimer(sess, OperandB, Offset, Operation);
     return(tpm._GetLastResponseCode());
 }
Beispiel #44
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);
        }
Beispiel #45
0
 internal override TpmRc Execute(Tpm2 tpm, AuthSession sess, PolicyTree policy)
 {
     tpm.PolicyLocality(sess, AllowedLocality);
     return(tpm._GetLastResponseCode());
 }
Beispiel #46
0
        /// <summary>
        /// This sample demonstrates how policies can be created in a standard
        /// form and then shared between hosts.
        /// </summary>
        static void PolicySerialization()
        {
            Console.WriteLine("Policy serialization and de-serialization sample:");

            //
            // Create a policy session with two branches
            //
            var policy0 = new PolicyTree(TpmAlgId.Sha256);

            policy0.CreateNormalizedPolicy(new[] {
                new PolicyAce[]
                {
                    new TpmPolicyPassword(), 
                    new TpmPolicyLocality(LocalityAttr.TpmLocZero),
                    new TpmPolicyChainId("branch_1")
                },
                new PolicyAce[]
                {
                    new TpmPolicyPassword(), 
                    new TpmPolicyCommand(TpmCc.ChangeEPS),
                    "branch_2"
                }
            });

            //
            // And save it to disk as XML
            //
            const string fileName = "PolicySerialization.xml";
            policy0.SerializeToFile("Test Policy",  PolicySerializationFormat.Xml, fileName);

            //
            // Now recover it into a new session 
            //
            var policy1 = new PolicyTree(TpmAlgId.Sha256);
            policy1.DeserializeFromFile(PolicySerializationFormat.Xml, fileName);

            //
            // And check that the two policies are the same
            //
            if (policy0.GetPolicyDigest() != policy1.GetPolicyDigest())
            {
                throw new Exception("Policy library error");
            }

            Console.WriteLine("Serialized policy to {0}.", fileName);

            //
            // And now do the same, but serialized to JSON
            //
            const string fileNameJ = "PolicySerialization.json";
            policy0.SerializeToFile("Test Policy", PolicySerializationFormat.Json, fileNameJ);

            //
            // Now recover it into a new session 
            //
            var policy1J = new PolicyTree(TpmAlgId.Sha256);
            policy1J.DeserializeFromFile(PolicySerializationFormat.Json, fileNameJ);

            //
            // And check that the two policies are the same
            //
            if (policy0.GetPolicyDigest() != policy1J.GetPolicyDigest())
            {
                throw new Exception("Policy library error");
            }

            Console.WriteLine("Serialized policy to {0}.", fileNameJ);


        }
Beispiel #47
0
 internal override TpmRc Execute(Tpm2 tpm, AuthSession sess, PolicyTree policy)
 {
     Globs.Throw("Do not include PolicyRestart in running policies");
     return(TpmRc.Policy);
 }
Beispiel #48
0
        /// <summary>
        /// The callback to sign the TpmPolicySignature challenge from the TPM.
        /// </summary>
        /// <param name="policyTree">The policy tree to check.</param>
        /// <param name="ace">The policy element (TpmPolicySignature) to evaluate.</param>
        /// <param name="nonceTpm">The nonce from the TPM.</param>
        /// <returns>Signature of the nonce.</returns>
        public static ISignatureUnion SignerCallback(PolicyTree policyTree, TpmPolicySigned ace, 
            byte[] nonceTpm, out TpmPublic verificationKey)
        {
            //
            // This function checks the parameters of the associated TpmPolicySigned
            // ACE, and if they are those expected the TPM challenge is signed.
            // Note that policy expressions are often obtained from untrustworthy
            // sources, so it is important for key-holders to check what they 
            // are bing asked to do before signing anything.
            //

            // 
            // The policy just contains the name of the signature verification key, however the
            // TPM needs the actual public key to verify the signature.  Check that the name
            // matches, and if it does return the public key.
            //
            byte[] expectedName = _publicSigningKey.GetPublicParms().GetName();
            if (!expectedName.SequenceEqual(ace.AuthObjectName))
            {
                throw new Exception("Unexpected name in policy.");
            }
            verificationKey = _publicSigningKey.GetPublicParms();
            
            // 
            // Check that the key is the one that we expect
            // 
            if (ace.NodeId != "Signing Key 1")
            {
                throw new Exception("Unrecognized key");
            }


            //
            // Check that nonceTom is not null (otherwise anything we sign can
            // be used for any session).
            // 
            if (nonceTpm.Length == 0)
            {
                throw new Exception("Sign challenges with expiration time need nonce.");
            }

            //
            // Check PolicyRef and cpHash are what we want to sign
            // 
            if (ace.CpHash.Length != 0)
            {
                throw new Exception("I only sign null-cpHash");
            }

            if (!ace.PolicyRef.SequenceEqual(new byte[] { 1, 2, 3, 4 }))
            {
                throw new Exception("Incorrect PolicyRef");
            }

            //
            // And finally check that the expiration is set correctly. Check for
            // positive values (simple signing policy) and negative values (sining 
            // policy with ticket).
            // 
            if (ace.ExpirationTime != _expectedExpirationTime)
            {
                throw new Exception("Unexpected expiration time");
            }

            //
            // Everything is OK, so get a formatted bloc containing the challenge 
            // data and then sign it.
            // 
            byte[] dataStructureToSign = PolicyTree.GetDataStructureToSign(ace.ExpirationTime,
                                                                                 nonceTpm,
                                                                                 ace.CpHash,
                                                                                 ace.PolicyRef);
            ISignatureUnion signature = _publicSigningKey.Sign(dataStructureToSign);
            return signature;
        }
Beispiel #49
0
 internal override TpmRc Execute(Tpm2 tpm, AuthSession sess, PolicyTree policy)
 {
     tpm.PolicyPhysicalPresence(sess);
     return(tpm._GetLastResponseCode());
 }
Beispiel #50
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);
        }
Beispiel #51
0
 /// <summary>
 /// This callback function provides authorization in plain text
 /// </summary>
 static public void PolicySecretCallback(
     PolicyTree policyTree,
     TpmPolicySecret ace,
     out SessionBase authorizingSession,
     out TpmHandle authorizedEntityHandle,
     out bool flushAuthEntity)
 {
     authorizingSession = _publicAuthorizationValue;
     authorizedEntityHandle = _publicSealedObjectHandle;
     flushAuthEntity = false;
 }
Beispiel #52
0
 // ReSharper disable once InconsistentNaming
 internal override TpmRc Execute(Tpm2 tpm, AuthSession authSession, PolicyTree policy)
 {
     if (ObjectName == null)
     {
         ObjectName = AuthorizingKey.GetName();
     }
     tpm.PolicyTicket(authSession,
                      ExpirationTime,
                      CpHash,
                      PolicyRef,
                      Marshaller.GetTpmRepresentation(ObjectName),
                      Ticket);
     return tpm._GetLastResponseCode();
 }