Exemplo n.º 1
0
        public TkVerified VerifySignatureOfRecivedMessage(TpmPublic keyPublic, byte[] message, ISignatureUnion signature)
        {
            TpmHash   dataToSign = TpmHash.FromData(TpmAlgId.Sha256, message);
            TpmHandle pubHandle  = tpm.LoadExternal(null, keyPublic, TpmHandle.RhOwner);

            return(tpm.VerifySignature(pubHandle, dataToSign.HashData, signature));
        }
Exemplo n.º 2
0
        public static ushort MaxOaepMsgSize(ushort keyBitLen, TpmAlgId hashAlg)
        {
            int keySize        = keyBitLen / 8;
            int maxMessageSize = keySize - 2 * TpmHash.DigestSize(hashAlg) - 2;

            return((ushort)(maxMessageSize > keySize || maxMessageSize < 0 ? 0 : maxMessageSize));
        }
Exemplo n.º 3
0
        static void ReadPcr()
        {
            Console.WriteLine("\nPCR sample started.");

            using (Tpm2Device tpmDevice = new TbsDevice())
            {
                tpmDevice.Connect();

                using (var tpm = new Tpm2(tpmDevice))
                {
                    var valuesToRead = new PcrSelection[]
                    {
                        new PcrSelection(TpmAlgId.Sha1, new uint[] { 1, 2 })
                    };

                    PcrSelection[] valsRead;
                    Tpm2bDigest[]  values;

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

                    if (valsRead[0] != valuesToRead[0])
                    {
                        Console.WriteLine("Unexpected PCR-set");
                    }

                    var pcr1 = new TpmHash(TpmAlgId.Sha1, values[0].buffer);
                    Console.WriteLine("PCR1: " + pcr1);

                    var dataToExtend = new byte[] { 0, 1, 2, 3, 4 };
                    tpm.PcrEvent(TpmHandle.Pcr(1), dataToExtend);
                    tpm.PcrRead(valuesToRead, out valsRead, out values);
                }
            }
        }
Exemplo n.º 4
0
        void ExternalKeyImportSample(Tpm2 tpm, TestContext testCtx)
        {
            // Create a software key (external to any TPM).
            int keySize        = 2048;
            var externalRsaKey = new RawRsa(keySize);

            // When an external key comes from a cert, one would need to extract the key size and
            // byte buffers representing public and private parts of the key from the cert, an use
            // them directly in the call to ImportExternalRsaKey() below (i.e. no RawRsa object is
            // necessary).

            // Signing scheme to use (it may come from the key's cert)
            TpmAlgId sigHashAlg = Substrate.Random(TpmCfg.HashAlgs);
            var      sigScheme  = new SchemeRsassa(sigHashAlg);

            // An arbitrary external key would not have TPM key attributes associated with it.
            // Yet some of them may be inferred from the cert based on the declared key purpose
            // (ObjectAttr.Sign below). The others are defined by the intended TPM key usage
            // scenarios, e.g. ObjectAttr.UserWithAuth tells TPM to allow key usage authorization
            // using an auth value (random byte buffer) in a password or an HMAC session.
            ObjectAttr keyAttrs = ObjectAttr.Sign | ObjectAttr.UserWithAuth;

            // Generate an auth value for the imported matching in strength the signing scheme
            byte[] authVal = Substrate.RandomAuth(sigHashAlg);

            // We need a storage key to use as a parent of the imported key.
            // The following helper creates an RSA primary storage key.
            TpmHandle hParent = Substrate.CreateRsaPrimary(tpm);

            TssObject importedKey = ImportExternalRsaKey(tpm, hParent,
                                                         keySize, sigScheme,
                                                         externalRsaKey.Public, externalRsaKey.Private,
                                                         keyAttrs, authVal);

            // Now we can load the newly imported key into the TPM, ...
            TpmHandle hImportedKey = tpm.Load(hParent, importedKey.Private, importedKey.Public);

            // ... let the TSS know the auth value associated with this handle, ...
            hImportedKey.SetAuth(authVal);

            // ... and use it to sign something to check if import was OK
            TpmHash         toSign = TpmHash.FromRandom(sigHashAlg);
            ISignatureUnion sig    = tpm.Sign(hImportedKey, toSign, null, new TkHashcheck());

            // Verify that the signature is correct using the public part of the imported key
            bool sigOk = importedKey.Public.VerifySignatureOverHash(toSign, sig);

            testCtx.Assert("Signature.OK", sigOk);

            // Cleanup
            tpm.FlushContext(hImportedKey);
            // The parent key handle can be flushed immediately after it was used in the Load() command
            tpm.FlushContext(hParent);

            // Imported private/public key pair (in the TssObject) can be stored on disk, in the cloud,
            // etc. (no additional protection is necessary), and loaded into the TPM as above whenever
            // the key is needed.

            // Alternatively the key can be persisted in the TPM using the EvictControl() command
        } // ExternalKeyImportSample
Exemplo n.º 5
0
        void TestSerialization(Tpm2 tpm, TestContext testCtx)
        {
            // test library serialization (not a TPM test)
            TpmAlgId hashAlg = Substrate.Random(TpmCfg.HashAlgs);

            // make some moderately complicated TPM structures
            var inPub = new TpmPublic(hashAlg,
                                      ObjectAttr.Sign | ObjectAttr.FixedParent | ObjectAttr.FixedTPM
                                      | ObjectAttr.UserWithAuth | ObjectAttr.SensitiveDataOrigin,
                                      null,
                                      new RsaParms(new SymDefObject(), new SchemeRsassa(hashAlg),
                                                   Substrate.Random(TpmCfg.RsaKeySizes), 0),
                                      new Tpm2bPublicKeyRsa());

            TpmPublic pub;
            TpmHandle hKey = Substrate.CreateAndLoad(tpm, inPub, out pub);

            TpmHash hashToSign = TpmHash.FromRandom(hashAlg);
            var     proof      = new TkHashcheck(TpmRh.Null, null);
            var     sig        = tpm.Sign(hKey, hashToSign, new SchemeRsassa(hashAlg), proof);

            tpm.FlushContext(hKey);

            // Simple TPM-hash to/from JSON
            TpmHash h = TpmHash.FromString(hashAlg, "hello");

            MemoryStream s2 = new MemoryStream();
            DataContractJsonSerializer ser2 = new DataContractJsonSerializer(typeof(TpmHash));

            ser2.WriteObject(s2, h);
            s2.Flush();
            string jsonString2 = Encoding.ASCII.GetString(s2.ToArray());

            TpmHash h2 = (TpmHash)ser2.ReadObject(new MemoryStream(s2.ToArray()));

            testCtx.AssertEqual("JSON.Simple", h, h2);

            // JSON more complex -
            MemoryStream s = new MemoryStream();
            DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(TpmPublic));

            ser.WriteObject(s, pub);
            s.Flush();
            string    jsonString  = Encoding.ASCII.GetString(s.ToArray());
            TpmPublic reconstruct = (TpmPublic)ser.ReadObject(new MemoryStream(s.ToArray()));

            testCtx.AssertEqual("JSON.Complex", pub, reconstruct);

            // XML
            s = new MemoryStream();
            DataContractSerializer s4 = new DataContractSerializer(typeof(TpmPublic));

            s4.WriteObject(s, pub);
            s.Flush();
            string    xmlString = Encoding.ASCII.GetString(s.ToArray());
            TpmPublic rec4      = (TpmPublic)s4.ReadObject(new MemoryStream(s.ToArray()));

            testCtx.AssertEqual("XML.Complex", pub, rec4, s4);
        } // TestSerialization
Exemplo n.º 6
0
        void TestCertifyX509_1(Tpm2 tpm, TestContext testCtx)
        {
            testCtx.ReportParams("Test phase: TestCertifyX509_1");

            var policy = new PolicyTree(TpmAlgId.Sha256);

            policy.SetPolicyRoot(new TpmPolicyCommand(TpmCc.CertifyX509));

            var keyTemplate = new TpmPublic(
                TpmAlgId.Sha256,
                ObjectAttr.Restricted | ObjectAttr.Sign | ObjectAttr.FixedParent | ObjectAttr.FixedTPM | ObjectAttr.UserWithAuth | ObjectAttr.AdminWithPolicy | ObjectAttr.SensitiveDataOrigin,
                policy.GetPolicyDigest(),
                new RsaParms(new SymDefObject(), new SchemeRsassa(TpmAlgId.Sha256), 2048, 0),
                new Tpm2bPublicKeyRsa()
                );

            // Make two keys
            TpmPublic certifyingKeyPub, keyToBeCertifiedPub;
            TpmHandle hCertifyingKey    = Substrate.CreatePrimary(tpm, keyTemplate, out certifyingKeyPub);
            TpmHandle hKeyToBeCertified = Substrate.CreatePrimary(tpm, keyTemplate, out keyToBeCertifiedPub);

            var partialCert      = CertifyX509Support.MakeExemplarPartialCert();
            var partialCertBytes = partialCert.GetDerEncoded();

            // If you want to paste in your own hex put it here and s
            //var partialCertBytes = Globs.ByteArrayFromHex("01020304");

            AuthSession sess = tpm.StartAuthSessionEx(TpmSe.Policy, TpmAlgId.Sha256);

            sess.RunPolicy(tpm, policy);

            // I used this to test that the auth is OK.  Of course you need to change the PolicyCommandCode above
            //var attestInfo = tpm[sess].Certify(hKeyToBeCertified, hCertifyingKey, new byte[0], new NullSigScheme(), out var legacySignature);

            byte[]          tbsHash;
            ISignatureUnion signature;

            byte[] addedTo     = tpm[sess].CertifyX509(hKeyToBeCertified, hCertifyingKey, new byte[0], new NullSigScheme(), partialCertBytes, out tbsHash, out signature);
            var    addedToCert = AddedToCertificate.FromDerEncoding(addedTo);

            var returnedCert = CertifyX509Support.AssembleCertificate(partialCert, addedToCert, ((SignatureRsa)signature).GetTpmRepresentation());

            // Does the expected hash match the returned hash?
            var tbsBytes        = returnedCert.GetTbsCertificate();
            var expectedTbsHash = TpmHash.FromData(TpmAlgId.Sha256, tbsBytes);

            Debug.Assert(Globs.ArraysAreEqual(expectedTbsHash.HashData, tbsHash));

            // If you get this far we can check the cert is properly signed but we'll need to do a
            // bit of TPM<->Bouncy Castle data type conversion.


            tpm.FlushContext(hCertifyingKey);
            tpm.FlushContext(hKeyToBeCertified);
        } // TestCertifyX509_1
Exemplo n.º 7
0
        } // CreateRsaPrimaryStorageKey()

        /// <summary>
        /// This sample illustrates the creation and use of an RSA signing key to
        /// "quote" PCR state
        /// </summary>
        /// <param name="tpm">Reference to the TPM object.</param>
        static void QuotePcrs(Tpm2 tpm)
        {
            Console.WriteLine("\nPCR Quote sample started.");

            //
            // First use a library routine to create an RSA/AES primary storage key
            // with null user-auth.
            //
            TpmHandle primHandle = CreateRsaPrimaryStorageKey(tpm);

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

            //
            // Creation data (not used in this sample)
            //
            CreationData childCreationData;
            TkCreation   creationTicket;

            byte[] creationHash;

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

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

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

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

            //
            // A nonce (or qualifying data)
            //
            TpmHash nonce = TpmHash.FromData(TpmAlgId.Sha256, new byte[] { 4, 3, 2, 1 });

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

            //
            // Ask the TPM to quote the PCR (with the given nonce).  The TPM
            // returns both the signature and the quote data that were signed.
            //
            ISignatureUnion quoteSig;
            Attest          quotedInfo = tpm.Quote(hSigKey,
                                                   nonce,
                                                   new SchemeRsassa(TpmAlgId.Sha256),
                                                   pcrsToQuote,
                                                   out quoteSig);
            //
            // Print out what was quoted
            //
            var info = (QuoteInfo)quotedInfo.attested;

            Console.WriteLine("PCRs that were quoted: " +
                              info.pcrSelect[0].ToString() +
                              "\nHash of PCR-array: " +
                              BitConverter.ToString(info.pcrDigest));

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

            //
            // Use the TSS.Net library to validate the quote against the
            // values just read.
            //
            bool quoteOk = keyPub.VerifyQuote(TpmAlgId.Sha256, outSelection, outValues,
                                              nonce, quotedInfo, quoteSig);

            if (!quoteOk)
            {
                throw new Exception("Quote did not validate");
            }

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

            //
            // Test other uses of the signing key.  A restricted key can only
            // sign data that the TPM knows does not start with a magic
            // number (that identifies TPM internal data).  So this does not
            // work
            //
            var nullProof = new TkHashcheck(TpmHandle.RhNull, null);

            tpm._ExpectError(TpmRc.Ticket)
            .Sign(hSigKey, nonce, new SchemeRsassa(TpmAlgId.Sha256), nullProof);

            //
            // But if we ask the TPM to hash the same data and then sign it
            // then the TPM can be sure that the data is safe, so it will
            // sign it.
            //
            TkHashcheck tkSafeHash;
            TpmHandle   hashHandle = tpm.HashSequenceStart(null, TpmAlgId.Sha256);

            //
            // The ticket is only generated if the data is "safe."
            //
            tpm.SequenceComplete(hashHandle, new byte[] { 4, 3, 2, 1 },
                                 TpmRh.Owner, out tkSafeHash);
            //
            // This will now work because the ticket proves to the
            // TPM that the data that it is about to sign does not
            // start with TPM_GENERATED
            //
            ISignatureUnion sig = tpm.Sign(hSigKey, nonce,
                                           new SchemeRsassa(TpmAlgId.Sha256), tkSafeHash);
            //
            // And we can verify the signature
            //
            bool sigOk = keyPub.VerifySignatureOverData(new byte[] { 4, 3, 2, 1 }, sig);

            if (!sigOk)
            {
                throw new Exception("Signature did not verify");
            }

            Console.WriteLine("Signature verified.");

            //
            // Clean up
            //
            tpm.FlushContext(primHandle);
            tpm.FlushContext(hSigKey);

            Console.WriteLine("PCR Quote sample finished.");
        } // QuotePcrs()
Exemplo n.º 8
0
        /// <summary>
        /// This sample demonstrates the use of the TPM Platform Configuration
        /// Registers (PCR). TSS.Net provides several features to model PCR
        /// semantics.
        /// </summary>
        /// <param name="tpm">Reference to the TPM object.</param>
        static void Pcrs(Tpm2 tpm)
        {
            Console.WriteLine("\nPCR sample started.");

            //
            // Read the value of the SHA1 PCR 1 and 2
            //
            var valuesToRead = new PcrSelection[]
            {
                new PcrSelection(TpmAlgId.Sha256, new uint[] { 1, 2 })
            };

            PcrSelection[] valsRead;
            Tpm2bDigest[]  values;

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

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

            //
            // Print out PCR-1
            //
            var pcr1 = new TpmHash(TpmAlgId.Sha256, values[0].buffer);

            Console.WriteLine("PCR1: " + pcr1);

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

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

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

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

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

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

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

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

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

            Console.WriteLine("PCR sample finished.");
        } // Pcrs
Exemplo n.º 9
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);
        }
Exemplo n.º 10
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);
        }
Exemplo n.º 11
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.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 policy = new PolicyTree(TpmAlgId.Sha256);

            //
            // First branch of PolicyOr
            //
            var branch1 = new PolicyAce[]
            {
                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.
            //
            policy.CreateNormalizedPolicy(new[] { branch1, branch2 });

            //
            // Ask Tpm2Lib for the expected policy-hash for this policy
            //
            TpmHash expectedPolicyHash = policy.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, policy, "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, policy, "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);
        }
Exemplo n.º 12
0
        /// <summary>
        /// Performs the following operations:
        /// - Generates in software (using TSS.net helpers) a key with the given template,
        /// - Creates TPM-compatible dupliction blob for the given TPM based parent key,
        /// - Import the duplication blob into TPM
        /// - Loads the imported key into the TPM
        /// - Makes sure that the imported key works.
        /// </summary>
        /// <param name="tpm">TPM instance to use</param>
        /// <param name="keyPub">Template for the software generated key.</param>
        /// <param name="hParent">Intended TPM based parent key for the software generated key.</param>
        /// <param name="innerSymDef">Specification of the optional inner wrapper for the duplication blob.</param>
        static void GenerateAndImport(Tpm2 tpm, TpmPublic keyPub, TpmHandle hParent,
                                      SymDefObject innerSymDef = null)
        {
            //
            // Create a software key with the given template
            //

            // Generate a random auth value for the key to be created (though we could
            // use an empty buffer, too).
            var keyAuth = AuthValue.FromRandom(CryptoLib.DigestSize(keyPub.nameAlg));

            // Generate the key
            TssObject swKey = TssObject.Create(keyPub, keyAuth);

            //
            // Create duplication blob for the new key with the SRK as the new parent
            //

            // Create a symmetric software key if an inner wrapper is requested.
            var innerWrapKey = innerSymDef == null ? null : SymCipher.Create(innerSymDef);

            // Retrieve the public area of the intended parent key from the TPM
            // We do not need the name (and qualified name) of the key here, but
            // the TPM command returns them anyway.
            // NOTE - Alternatively we could get the public area from the overloaded
            // form of the CreateRsaPrimaryStorageKey() helper used to create the parent
            // key, as all TPM key creation commands (TPM2_CreatePrimary(), TPM2_Create()
            // and TPM2_CreateLoaded()) return it.
            byte[]    name, qname;
            TpmPublic pubParent = tpm.ReadPublic(hParent, out name, out qname);

            byte[]     encSecret;
            TpmPrivate dupBlob = swKey.GetDuplicationBlob(pubParent, innerWrapKey, out encSecret);

            // Import the duplication blob into the TPM
            TpmPrivate privImp = tpm.Import(hParent, innerWrapKey, swKey.Public, dupBlob,
                                            encSecret, innerSymDef ?? new SymDefObject());

            // Load the imported key ...
            TpmHandle hKey = tpm.Load(hParent, privImp, swKey.Public)
                             .SetAuth(swKey.Sensitive.authValue);

            // ... and validate that it works
            byte[] message = Globs.GetRandomBytes(32);

            if (keyPub.objectAttributes.HasFlag(ObjectAttr.Decrypt))
            {
                // Encrypt something
                if (keyPub.type == TpmAlgId.Symcipher)
                {
                    // Only need software symcypher here to query IV size.
                    // Normally, when you use a fixed algorithm, you can hardcode it.
                    var    swSym = SymCipher.Create(keyPub.parameters as SymDefObject);
                    byte[] ivIn  = Globs.GetRandomBytes(swSym.IVSize),
                    ivOut = null;
                    byte[] cipher = swKey.Encrypt(message, ref ivIn, out ivOut);

                    // Not all TPMs implement TPM2_EncryptDecrypt() command
                    tpm._ExpectResponses(TpmRc.Success, TpmRc.TbsCommandBlocked);
                    byte[] decrypted = tpm.EncryptDecrypt(hKey, 1, TpmAlgId.Null, ivIn,
                                                          cipher, out ivOut);
                    if (tpm._LastCommandSucceeded())
                    {
                        bool decOk = Globs.ArraysAreEqual(message, decrypted);
                        Console.WriteLine("Imported symmetric key validation {0}",
                                          decOk ? "SUCCEEDED" : "FAILED");
                    }
                }
            }
            else
            {
                // Sign something (works for both asymmetric and MAC keys)
                string keyType = keyPub.type == TpmAlgId.Rsa ? "RSA"
                               : keyPub.type == TpmAlgId.Keyedhash ? "HMAC"
                               : "UNKNOWN"; // Should not happen in this sample
                TpmAlgId        sigHashAlg = GetSchemeHash(keyPub);
                TpmHash         toSign     = TpmHash.FromData(sigHashAlg, message);
                var             proofx     = new TkHashcheck(TpmRh.Null, null);
                ISignatureUnion sig        = tpm.Sign(hKey, toSign, null, proofx);
                bool            sigOk      = swKey.VerifySignatureOverHash(toSign, sig);
                Console.WriteLine("Imported {0} key validation {1}", keyType,
                                  sigOk ? "SUCCEEDED" : "FAILED");
            }

            // Free TPM resources taken by the loaded imported key
            tpm.FlushContext(hKey);
        } // GenerateAndImport
Exemplo n.º 13
0
 public int MaxDataObjectSize(TpmAlgId nameAlg = TpmAlgId.Null)
 {
     return(TpmVersion < 149 ? (int)TpmHash.DigestSize(nameAlg) : (int)Implementation.MaxSymData);
 }
Exemplo n.º 14
0
        public SignatureRsassa SignMessageToSend(TpmHandle keyHandle, byte[] message)
        {
            TpmHash dataToSign = TpmHash.FromData(TpmAlgId.Sha1, message);

            return(tpm.Sign(keyHandle, dataToSign.HashData, new NullSigScheme(), TpmHashCheck.NullHashCheck()) as SignatureRsassa);
        }
Exemplo n.º 15
0
        static void Sign()
        {
            using (Tpm2Device tpmDevice = Examples.GetSimulator())
            {
                tpmDevice.Connect();

                using (var tpm = new Tpm2(tpmDevice))
                {
                    if (tpmDevice is TcpTpmDevice)
                    {
                        tpmDevice.PowerCycle();
                    }



                    CreateRsaPrimaryKey(tpm, tpmDevice is TcpTpmDevice);

                    var keyTemplate = new TpmPublic(TpmAlgId.Sha1,                                 // Name algorithm
                                                    ObjectAttr.UserWithAuth | ObjectAttr.Sign |    // Signing key
                                                    ObjectAttr.FixedParent | ObjectAttr.FixedTPM | // Non-migratable
                                                    ObjectAttr.SensitiveDataOrigin,
                                                    null,                                          // No policy
                                                    new RsaParms(new SymDefObject(),
                                                                 new SchemeRsassa(TpmAlgId.Sha1), 2048, 0),
                                                    new Tpm2bPublicKeyRsa());

                    var ownerAuth = new AuthValue();

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

                    TpmPublic    keyPublic;
                    CreationData creationData;
                    TkCreation   creationTicket;
                    byte[]       creationHash;

                    TpmHandle keyHandle = tpm[ownerAuth].CreatePrimary(
                        TpmRh.Owner,                                             // In the owner-hierarchy
                        new SensitiveCreate(keyAuth, null),                      // With this auth-value
                        keyTemplate,                                             // Describes key
                        null,                                                    // Extra data for creation ticket
                        new PcrSelection[0],                                     // Non-PCR-bound
                        out keyPublic,                                           // PubKey and attributes
                        out creationData, out creationHash, out creationTicket); // Not used here

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

                    byte[]  message      = Encoding.Unicode.GetBytes("ABC");
                    TpmHash digestToSign = TpmHash.FromData(TpmAlgId.Sha1, message);

                    var signature = tpm[keyAuth].Sign(keyHandle,    // Handle of signing key
                                                      digestToSign, // Data to sign
                                                      null,         // Use key's scheme
                                                      TpmHashCheck.Null()) as SignatureRsassa;
                    //
                    // Print the signature.
                    //
                    Console.WriteLine("Signature: " + BitConverter.ToString(signature.sig));


                    bool sigOk = keyPublic.VerifySignatureOverData(message, signature);
                    if (!sigOk)
                    {
                        throw new Exception("Signature did not validate.");
                    }

                    Console.WriteLine("Verified signature with TPM2lib (software implementation).");

                    TpmHandle pubHandle = tpm.LoadExternal(null, keyPublic, TpmRh.Owner);
                    tpm.VerifySignature(pubHandle, digestToSign, signature);
                    Console.WriteLine("Verified signature with TPM.");
                }
            }
        }
Exemplo n.º 16
0
        } // StorageRootKey()

        /// <summary>
        /// This sample demonstrates the async interface to the TPM for selected slow operations.
        /// await-async is preferred when calling slow TPM functions on a UI-thread.  Only a few TPM
        /// functions have an async-form.
        /// </summary>
        /// <param name="tpm">Reference to TPM object</param>
        /// <param name="Event">Synchronization object to signal calling function when we're done.</param>
        static async void PrimarySigningKeyAsync(Tpm2 tpm, AutoResetEvent Event)
        {
            //
            // The TPM needs a template that describes the parameters of the key
            // or other object to be created.  The template below instructs the TPM
            // to create a new 2048-bit non-migratable signing key.
            //
            var keyTemplate = new TpmPublic(TpmAlgId.Sha256,                               // Name algorithm
                                            ObjectAttr.UserWithAuth | ObjectAttr.Sign |    // Signing key
                                            ObjectAttr.FixedParent | ObjectAttr.FixedTPM | // Non-migratable
                                            ObjectAttr.SensitiveDataOrigin,
                                            null,                                          // No policy
                                            new RsaParms(new SymDefObject(),
                                                         new SchemeRsassa(TpmAlgId.Sha256), 2048, 0),
                                            new Tpm2bPublicKeyRsa());
            //
            // Authorization for the key we are about to create
            //
            var keyAuth = new byte[] { 1, 2, 3 };

            //
            // Ask the TPM to create a new primary RSA signing key
            //
            Tpm2CreatePrimaryResponse newPrimary = await tpm.CreatePrimaryAsync(
                TpmRh.Owner,                                                    // In the owner-hierarchy
                new SensitiveCreate(keyAuth, null),                             // With this auth-value
                keyTemplate,                                                    // Key params
                null,                                                           // For creation ticket
                new PcrSelection[0]);                                           // For creation ticket

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

            //
            // Use the key to sign some data
            //
            byte[]  message    = Encoding.Unicode.GetBytes("ABC");
            TpmHash dataToSign = TpmHash.FromData(TpmAlgId.Sha256, message);
            var     sig        = await tpm.SignAsync(newPrimary.handle,                 // Signing key handle
                                                     dataToSign,                        // Data to sign
                                                     new SchemeRsassa(TpmAlgId.Sha256), // Default scheme
                                                     TpmHashCheck.Null());

            //
            // Print the signature. A different structure is returned for each
            // signing scheme, so cast the interface to our signature type.
            //
            var actualSig = (SignatureRsassa)sig;

            Console.WriteLine("Signature: " + BitConverter.ToString(actualSig.sig));

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

            //
            // Tell caller, we're done.
            //
            Event.Set();
        }
Exemplo n.º 17
0
        /// <summary>
        /// This sample demonstrates the creation of a signing "primary" key and use of this
        /// key to sign data, and use of the TPM and TSS.Net to validate the signature.
        /// </summary>
        /// <param name="args">Arguments to this program.</param>
        static void Main(string[] args)
        {
            //
            // Parse the program arguments. If the wrong arguments are given or
            // are malformed, then instructions for usage are displayed and
            // the program terminates.
            //
            string tpmDeviceName;

            if (!ParseArguments(args, out tpmDeviceName))
            {
                WriteUsage();
                return;
            }

            try
            {
                //
                // Create the device according to the selected connection.
                //
                Tpm2Device tpmDevice;
                switch (tpmDeviceName)
                {
                case DeviceSimulator:
                    tpmDevice = new TcpTpmDevice(DefaultSimulatorName, DefaultSimulatorPort);
                    break;

                case DeviceWinTbs:
                    tpmDevice = new TbsDevice();
                    break;

                default:
                    throw new Exception("Unknown device selected.");
                }
                //
                // Connect to the TPM device. This function actually establishes the
                // connection.
                //
                tpmDevice.Connect();

                //
                // Pass the device object used for communication to the TPM 2.0 object
                // which provides the command interface.
                //
                var tpm = new Tpm2(tpmDevice);
                if (tpmDevice is TcpTpmDevice)
                {
                    //
                    // If we are using the simulator, we have to do a few things the
                    // firmware would usually do. These actions have to occur after
                    // the connection has been established.
                    //
                    tpmDevice.PowerCycle();
                    tpm.Startup(Su.Clear);
                }

                //
                // AuthValue encapsulates an authorization value: essentially a byte-array.
                // OwnerAuth is the owner authorization value of the TPM-under-test.  We
                // assume that it (and other) auths are set to the default (null) value.
                // If running on a real TPM, which has been provisioned by Windows, this
                // value will be different. An administrator can retrieve the owner
                // authorization value from the registry.
                //
                var ownerAuth = new AuthValue();

                //
                // The TPM needs a template that describes the parameters of the key
                // or other object to be created.  The template below instructs the TPM
                // to create a new 2048-bit non-migratable signing key.
                //
                var keyTemplate = new TpmPublic(TpmAlgId.Sha1,                                 // Name algorithm
                                                ObjectAttr.UserWithAuth | ObjectAttr.Sign |    // Signing key
                                                ObjectAttr.FixedParent | ObjectAttr.FixedTPM | // Non-migratable
                                                ObjectAttr.SensitiveDataOrigin,
                                                null,                                          // No policy
                                                new RsaParms(new SymDefObject(),
                                                             new SchemeRsassa(TpmAlgId.Sha1), 2048, 0),
                                                new Tpm2bPublicKeyRsa());

                //
                // Authorization for the key we are about to create.
                //
                var keyAuth = new byte[] { 1, 2, 3 };

                TpmPublic    keyPublic;
                CreationData creationData;
                TkCreation   creationTicket;
                byte[]       creationHash;

                //
                // Ask the TPM to create a new primary RSA signing key.
                //
                TpmHandle keyHandle = tpm[ownerAuth].CreatePrimary(
                    TpmRh.Owner,                                             // In the owner-hierarchy
                    new SensitiveCreate(keyAuth, null),                      // With this auth-value
                    keyTemplate,                                             // Describes key
                    null,                                                    // Extra data for creation ticket
                    new PcrSelection[0],                                     // Non-PCR-bound
                    out keyPublic,                                           // PubKey and attributes
                    out creationData, out creationHash, out creationTicket); // Not used here

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

                //
                // Use the key to sign some data
                //
                byte[]  message      = Encoding.Unicode.GetBytes("ABC");
                TpmHash digestToSign = TpmHash.FromData(TpmAlgId.Sha1, message);

                //
                // A different structure is returned for each signing scheme,
                // so cast the interface to our signature type (see third argument).
                //
                // As an alternative, 'signature' can be of type ISignatureUnion and
                // cast to SignatureRssa whenever a signature specific type is needed.
                //
                var signature = tpm[keyAuth].Sign(keyHandle,            // Handle of signing key
                                                  digestToSign,         // Data to sign
                                                  null,                 // Use key's scheme
                                                  TpmHashCheck.Null()) as SignatureRsassa;
                //
                // Print the signature.
                //
                Console.WriteLine("Signature: " + BitConverter.ToString(signature.sig));

                //
                // Use the TPM library to validate the signature
                //
                bool sigOk = keyPublic.VerifySignatureOverData(message, signature);
                if (!sigOk)
                {
                    throw new Exception("Signature did not validate.");
                }

                Console.WriteLine("Verified signature with TPM2lib (software implementation).");

                //
                // Load the public key into another slot in the TPM and then
                // use the TPM to validate the signature
                //
                TpmHandle pubHandle = tpm.LoadExternal(null, keyPublic, TpmRh.Owner);
                tpm.VerifySignature(pubHandle, digestToSign, signature);
                Console.WriteLine("Verified signature with TPM.");

                //
                // The default behavior of Tpm2Lib is to create an exception if the
                // signature does not validate. If an error is expected the library can
                // be notified of this, or the exception can be turned into a value that
                // can be later queried. The following are examples of this.
                //
                signature.sig[0] ^= 1;
                tpm._ExpectError(TpmRc.Signature)
                .VerifySignature(pubHandle, digestToSign, signature);

                if (tpm._GetLastResponseCode() != TpmRc.Signature)
                {
                    throw new Exception("TPM returned unexpected return code.");
                }

                Console.WriteLine("Verified that invalid signature causes TPM_RC_SIGNATURE return code.");

                //
                // Clean up of used handles.
                //
                tpm.FlushContext(keyHandle);
                tpm.FlushContext(pubHandle);

                //
                // (Note that serialization is not supported on WinRT)
                //
                // Demonstrate the use of XML persistence by saving keyPublic to
                // a file and making a copy by reading it back into a new object
                //
                // NOTE: 12-JAN-2016: May be removing support for policy
                //       serialization. We'd like to get feedback on whether
                //       this is a desirable feature and should be retained.
                //
                // {
                //     const string fileName = "sample.xml";
                //     string xmlVersionOfObject = keyPublic.GetXml();
                //     keyPublic.XmlSerializeToFile(fileName);
                //     var copyOfPublic = TpmStructureBase.XmlDeserializeFromFile<TpmPublic>(fileName);
                //
                //     //
                //     // Demonstrate Tpm2Lib support of TPM-structure equality operators
                //     //
                //     if (copyOfPublic != keyPublic)
                //     {
                //         Console.WriteLine("Library bug persisting data.");
                //     }
                // }
                //

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

            Console.WriteLine("Press Any Key to continue.");
            Console.ReadLine();
        }
Exemplo n.º 18
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.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 policy = 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.
            //
            policy.Create(
                new PolicyAce[]
            {
                new TpmPolicyPcr(expectedPcrVals),
                "leaf"
            }
                );

            //
            // Ask Tpm2Lib for the expected policy-hash for this policy
            //
            TpmHash expectedPolicyHash = policy.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, policy, "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, policy, 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);
        }
Exemplo n.º 19
0
 // returns PCR values after TPM Reset.
 // NOTE: PCR_Reset() comamnd always resets PCR contents to zeroes.
 // TODO: use TPM PCR properties
 public static TpmHash GetPcrResetValue(TpmAlgId hashAlg, int pcrNum)
 {
     return(pcrNum >= 17 && pcrNum <= 22 ? TpmHash.AllOnesHash(hashAlg)
                                         : TpmHash.ZeroHash(hashAlg));
 }
Exemplo n.º 20
0
        void TestCertifyX509Impl(Tpm2 tpm, TestContext testCtx,
                                 TpmPublic subjectTemplate, TpmPublic sigKeyTemplate,
                                 PolicyTree policy, string testLabel)
        {
            var partialCert      = X509Helpers.MakePartialCert(subjectTemplate);
            var partialCertBytes = partialCert.GetDerEncoded();

            // If you want to paste in your own hex put it here and s
            //var partialCertBytes = Globs.ByteArrayFromHex("01020304");

            // Certify RSA with RSA
            TpmPublic certifyingKeyPub, keyToBeCertifiedPub;
            TpmHandle hSigKey     = Substrate.CreatePrimary(tpm, sigKeyTemplate, out certifyingKeyPub);
            TpmHandle hSubjectKey = Substrate.CreatePrimary(tpm, subjectTemplate, out keyToBeCertifiedPub);

            AuthSession sess = tpm.StartAuthSessionEx(TpmSe.Policy, TpmAlgId.Sha256);

            sess.RunPolicy(tpm, policy);

            ISignatureUnion sig;

            byte[] tbsHash;
            byte[] addedTo = tpm[sess].CertifyX509(hSubjectKey, hSigKey,
                                                   null, new NullSigScheme(), partialCertBytes,
                                                   out tbsHash, out sig);

            tpm.FlushContext(sess);
            tpm.FlushContext(hSubjectKey);

            var             addedToCert  = AddedToCertificate.FromDerEncoding(addedTo);
            X509Certificate returnedCert = X509Helpers.AssembleCertificate(partialCert, addedToCert,
                                                                           sig is SignatureRsa ? ((SignatureRsa)sig).GetTpmRepresentation()
                                                        : ((SignatureEcc)sig).GetTpmRepresentation());

            // Does the expected hash match the returned hash?
            var tbsBytes        = returnedCert.GetTbsCertificate();
            var expectedTbsHash = TpmHash.FromData(TpmAlgId.Sha256, tbsBytes);

            Debug.Assert(Globs.ArraysAreEqual(expectedTbsHash.HashData, tbsHash));

            // Is the cert properly signed?
            if (TpmHelper.GetScheme(sigKeyTemplate).GetUnionSelector() != TpmAlgId.Rsapss)
            {
                // Software crypto layer does not support PSS
                bool sigOk = certifyingKeyPub.VerifySignatureOverHash(tbsHash, sig);
                if (sigKeyTemplate.type == TpmAlgId.Ecc)
                {
#if !__NETCOREAPP2__
                    // No ECC in .Net Core
                    testCtx.Assert("Sign" + testLabel, sigOk);
#endif
                }
                else
                {
                    testCtx.Assert("Sign" + testLabel, sigOk);
                }
            }
            tpm.VerifySignature(hSigKey, tbsHash, sig);

            tpm.FlushContext(hSigKey);
        }