Exemple #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));
        }
        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
Exemple #3
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();
        }
Exemple #4
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()
Exemple #5
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();
        }
Exemple #6
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);
        }
Exemple #7
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.");
                }
            }
        }
Exemple #8
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
Exemple #9
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);
        }