internal override TpmRc Execute(Tpm2 tpm, AuthSession sess, PolicyTree policy) { tpm.PolicyPassword(sess); sess.SessIncludesAuth = true; sess.PlaintextAuth = true; return(tpm._GetLastResponseCode()); }
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); }
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()); }
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); }
internal override TpmRc Execute(Tpm2 tpm, AuthSession sess, PolicyTree policy) { byte writtenName = IsNvIndexRequiredToHaveBeenWritten ? (byte)1 : (byte)0; tpm.PolicyNvWritten(sess, writtenName); return(tpm._GetLastResponseCode()); }
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()); }
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()); }
/// <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); }
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); }
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()); }
internal override TpmRc Execute(Tpm2 tpm, AuthSession authSession, PolicyTree policy) { tpm.PolicyAuthorizeNV(AuthHandle, NvIndex, authSession); return tpm._GetLastResponseCode(); }
// ReSharper disable once InconsistentNaming internal override TpmRc Execute(Tpm2 tpm, AuthSession authSession, PolicyTree policy) { return TpmRc.Success; }
/// <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); }
// 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(); }
// ReSharper disable once InconsistentNaming internal override TpmRc Execute(Tpm2 tpm, AuthSession authSession, PolicyTree policy) { policy.ExecutePolicyActionCallback(this); return TpmRc.Success; }
// 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; }
// 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; }
// ReSharper disable once InconsistentNaming internal override TpmRc Execute(Tpm2 tpm, AuthSession authSession, PolicyTree policy) { tpm.PolicyLocality(authSession, AllowedLocality); return tpm._GetLastResponseCode(); }
// ReSharper disable once InconsistentNaming internal override TpmRc Execute(Tpm2 tpm, AuthSession authSession, PolicyTree policy) { tpm.PolicyNameHash(authSession, NameHash); return tpm._GetLastResponseCode(); }
// ReSharper disable once InconsistentNaming internal override TpmRc Execute(Tpm2 tpm, AuthSession policySession, PolicyTree policy) { tpm.PolicyCounterTimer(policySession, OperandB, Offset, Operation); return tpm._GetLastResponseCode(); }
// 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(); }
internal override TpmRc Execute(Tpm2 tpm, AuthSession sess, PolicyTree policy) { policy.ExecutePolicyActionCallback(this); return(TpmRc.Success); }
// 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(); }
// 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(); }
// ReSharper disable once InconsistentNaming internal override TpmRc Execute(Tpm2 tpm, AuthSession authSession, PolicyTree policy) { tpm.PolicyPhysicalPresence(authSession); return tpm._GetLastResponseCode(); }
// 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; }
/// <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; }
/// <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; }
/// <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."); }
internal TpmPolicy(PolicyTree policy) { AssociatedPolicy = policy; PolicyRoot = policy.GetPolicyRoot(); PolicyHash = policy.GetPolicyDigest(); }
internal abstract TpmRc Execute(Tpm2 tpm, AuthSession sess, PolicyTree policy);
// 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(); }
internal override TpmRc Execute(Tpm2 tpm, AuthSession sess, PolicyTree policy) { tpm.PolicyPCR(sess, Pcrs.GetSelectionHash(policy.PolicyHash), Pcrs.GetPcrSelectionArray()); return(tpm._GetLastResponseCode()); }
internal override TpmRc Execute(Tpm2 tpm, AuthSession sess, PolicyTree policy) { tpm.PolicyAuthorizeNV(AuthHandle, NvIndex, sess); return(tpm._GetLastResponseCode()); }
internal override TpmRc Execute(Tpm2 tpm, AuthSession sess, PolicyTree policy) { tpm.PolicyNameHash(sess, NameHash); return(tpm._GetLastResponseCode()); }
internal override TpmRc Execute(Tpm2 tpm, AuthSession sess, PolicyTree policy) { return(TpmRc.Success); }
// 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(); }
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; }
// ReSharper disable once InconsistentNaming internal abstract TpmRc Execute(Tpm2 tpm, AuthSession authSession, PolicyTree policy);
internal override TpmRc Execute(Tpm2 tpm, AuthSession sess, PolicyTree policy) { Tpm2bDigest[] branchList = GetPolicyHashArray(policy.PolicyHash.HashAlg); tpm.PolicyOR(sess, branchList); return(tpm._GetLastResponseCode()); }
/// <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); }
internal override TpmRc Execute(Tpm2 tpm, AuthSession sess, PolicyTree policy) { tpm.PolicyCounterTimer(sess, OperandB, Offset, Operation); return(tpm._GetLastResponseCode()); }
/// <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); }
internal override TpmRc Execute(Tpm2 tpm, AuthSession sess, PolicyTree policy) { tpm.PolicyLocality(sess, AllowedLocality); return(tpm._GetLastResponseCode()); }
/// <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); }
internal override TpmRc Execute(Tpm2 tpm, AuthSession sess, PolicyTree policy) { Globs.Throw("Do not include PolicyRestart in running policies"); return(TpmRc.Policy); }
/// <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; }
internal override TpmRc Execute(Tpm2 tpm, AuthSession sess, PolicyTree policy) { tpm.PolicyPhysicalPresence(sess); return(tpm._GetLastResponseCode()); }
/// <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); }
/// <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; }
// 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(); }