示例#1
0
        public void Provision(string encodedHmacKey, string hostName, string deviceId = "")
        {
            TpmHandle    nvHandle      = new TpmHandle(AIOTH_PERSISTED_URI_INDEX + logicalDeviceId);
            TpmHandle    ownerHandle   = new TpmHandle(TpmRh.Owner);
            TpmHandle    hmacKeyHandle = new TpmHandle(AIOTH_PERSISTED_KEY_HANDLE + logicalDeviceId);
            TpmHandle    srkHandle     = new TpmHandle(SRK_HANDLE);
            UTF8Encoding utf8          = new UTF8Encoding();

            byte[] nvData  = utf8.GetBytes(hostName + "/" + deviceId);
            byte[] hmacKey = System.Convert.FromBase64String(encodedHmacKey);

            // Open the TPM
            Tpm2Device tpmDevice = new TbsDevice();

            tpmDevice.Connect();
            var tpm = new Tpm2(tpmDevice);

            // Define the store
            tpm.NvDefineSpace(ownerHandle,
                              new byte[0],
                              new NvPublic(nvHandle,
                                           TpmAlgId.Sha256,
                                           NvAttr.Authwrite | NvAttr.Authread | NvAttr.NoDa,
                                           new byte[0],
                                           (ushort)nvData.Length));

            // Write the store
            tpm.NvWrite(nvHandle, nvHandle, nvData, 0);

            // Import the HMAC key under the SRK
            TpmPublic    hmacPub;
            CreationData creationData;

            byte[]     creationhash;
            TkCreation ticket;
            TpmPrivate hmacPrv = tpm.Create(srkHandle,
                                            new SensitiveCreate(new byte[0],
                                                                hmacKey),
                                            new TpmPublic(TpmAlgId.Sha256,
                                                          ObjectAttr.UserWithAuth | ObjectAttr.NoDA | ObjectAttr.Sign,
                                                          new byte[0],
                                                          new KeyedhashParms(new SchemeHmac(TpmAlgId.Sha256)),
                                                          new Tpm2bDigestKeyedhash()),
                                            new byte[0],
                                            new PcrSelection[0],
                                            out hmacPub,
                                            out creationData,
                                            out creationhash,
                                            out ticket);

            // Load the HMAC key into the TPM
            TpmHandle loadedHmacKey = tpm.Load(srkHandle, hmacPrv, hmacPub);

            // Persist the key in NV
            tpm.EvictControl(ownerHandle, loadedHmacKey, hmacKeyHandle);

            // Unload the transient copy from the TPM
            tpm.FlushContext(loadedHmacKey);
        }
示例#2
0
    /// <summary>
    /// Provision the key in the TPM
    /// </summary>
    /// <param name="key">the access key</param>
    public void Provision(byte[] key)
    {
        TpmHandle ownerHandle   = new TpmHandle(TpmRh.Owner);
        TpmHandle hmacKeyHandle = new TpmHandle(PERSISTED_KEY_HANDLE + logicalDeviceId);
        TpmHandle srkHandle     = new TpmHandle(TPM_20_SRK_HANDLE);

        // Open the TPM
        Tpm2Device tpmDevice = new TbsDevice();

        tpmDevice.Connect();
        using (var tpm = new Tpm2(tpmDevice))
        {
#pragma warning disable IDE0059 // Value assigned to symbol is never used
            // Import the HMAC key under the SRK
            TpmPrivate hmacPrv = tpm.Create(srkHandle,
                                            new SensitiveCreate(Array.Empty <byte>(),
                                                                key),
                                            new TpmPublic(TpmAlgId.Sha256,
                                                          ObjectAttr.UserWithAuth | ObjectAttr.NoDA | ObjectAttr.Sign,
                                                          Array.Empty <byte>(),
                                                          new KeyedhashParms(new SchemeHmac(TpmAlgId.Sha256)),
                                                          new Tpm2bDigestKeyedhash()),
                                            Array.Empty <byte>(),
                                            Array.Empty <PcrSelection>(),
                                            out TpmPublic hmacPub,
                                            out CreationData creationData,
                                            out byte[] creationhash,
                                            out TkCreation ticket);
#pragma warning restore IDE0059 // Value assigned to symbol is never used

            // Load the HMAC key into the TPM
            TpmHandle loadedHmacKey = tpm.Load(srkHandle, hmacPrv, hmacPub);

            // Persist the key in NV
            tpm.EvictControl(ownerHandle, loadedHmacKey, hmacKeyHandle);

            // Unload the transient copy from the TPM
            tpm.FlushContext(loadedHmacKey);
        }
    }
示例#3
0
文件: Program.cs 项目: rgl/TSS.MSR
        } // 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()
示例#4
0
        /// <summary>
        /// Funzione per il salvataggio della chiave privata da utilizzare per firmare con HMAC tramite TPM
        /// </summary>
        /// <param name="encodedHmacKey"></param>
        public static void SaveHmacKey(string encodedHmacKey)
        {
            // Definizione area di memoria non volatile nel TPM
            TpmHandle nvHandle = new TpmHandle(AIOTH_PERSISTED_URI_INDEX + logicalDeviceId);

            // Definizione dell'handle contenente l'Owner nel TPM
            TpmHandle ownerHandle = new TpmHandle(TpmRh.Owner);

            // Definizione dell'handle per la memorizzazione dell'oggetto HMAC
            TpmHandle hmacKeyHandle = new TpmHandle(AIOTH_PERSISTED_KEY_HANDLE + logicalDeviceId);

            // Definizione dell'handle della Storage Root Key, si tratta della chiave
            // principale utilizzata per il salvataggio di altre chiavi. Ogni chiave salvata
            // nel TPM infatti viene cifrata utilizzando la sua chiave "padre".
            // La SRK è la chiave più alta dell'albero
            TpmHandle    srkHandle = new TpmHandle(SRK_HANDLE);
            UTF8Encoding utf8      = new UTF8Encoding();

            // dati descrittivi dell'host e del device id
            byte[] nvData = utf8.GetBytes(hostName + "/" + deviceId);

            // chiave privata che intendiamo memorizzare nel TPM
            byte[] hmacKey = System.Convert.FromBase64String(encodedHmacKey);

            // Apertura del TPM
            Tpm2Device tpmDevice = new TbsDevice();

            tpmDevice.Connect();
            var tpm = new Tpm2(tpmDevice);

            // Definizione dello store Non volatile
            // Il primo parametro è l'Owner TPM
            // il terzo parametro è la funzione HMAC che intendiamo salvare
            // (NvPublic sta per Non volatile public area)
            tpm.NvDefineSpace(ownerHandle,
                              new byte[0],
                              new NvPublic(
                                  nvHandle,
                                  TpmAlgId.Sha256,
                                  NvAttr.Authwrite | NvAttr.Authread | NvAttr.NoDa,
                                  new byte[0],
                                  (ushort)nvData.Length));

            // Scrittura nello store non volatile della funzione HMAC
            tpm.NvWrite(nvHandle, nvHandle, nvData, 0);

            // Importazione della chiave HMAC sotto la Storage Root Key
            TpmPublic    hmacPub;
            CreationData creationData;

            byte[]     creationhash;
            TkCreation ticket;

            // Passaggio della chiave privata
            var sensitiveCreate = new SensitiveCreate(new byte[0], hmacKey);

            // Definizione dell'uso che si farà della chiave
            var tpmPublic = new TpmPublic(
                TpmAlgId.Sha256,
                ObjectAttr.UserWithAuth | ObjectAttr.NoDA | ObjectAttr.Sign,
                new byte[0],
                new KeyedhashParms(new SchemeHmac(TpmAlgId.Sha256)),
                new Tpm2bDigestKeyedhash());

            // Salvataggio della chiave privata nel tpm
            TpmPrivate hmacPrv = tpm.Create(
                srkHandle,
                sensitiveCreate,
                tpmPublic,
                new byte[0],
                new PcrSelection[0],
                out hmacPub,
                out creationData,
                out creationhash,
                out ticket);

            // Caricamento della chiave HMAC nel TPM
            TpmHandle loadedHmacKey = tpm.Load(srkHandle, hmacPrv, hmacPub);

            // Salvataggio della chiave nella memoria Non Volatile
            tpm.EvictControl(ownerHandle, loadedHmacKey, hmacKeyHandle);

            // Flush degli oggetti transienti dal tpm
            tpm.FlushContext(loadedHmacKey);
        }
示例#5
0
        /// <summary>
        /// Creates a child of the given storage key, which can be used both for signing and decryption.
        /// Illustrates strict mode effect on automatic authorization handling.
        /// </summary>
        /// <returns>Handle of the created key.</returns>
        static TpmHandle CreateSigningDecryptionKey(Tpm2 tpm, TpmHandle primHandle, out TpmPublic keyPublic)
        {
            TpmPublic keyInPublic = new TpmPublic(
                TpmAlgId.Sha1,
                ObjectAttr.Decrypt | ObjectAttr.Sign | ObjectAttr.FixedParent | ObjectAttr.FixedTPM
                | ObjectAttr.UserWithAuth | ObjectAttr.SensitiveDataOrigin,
                null,
                new RsaParms(
                    new SymDefObject(),
                    new NullAsymScheme(),
                    2048, 0),
                new Tpm2bPublicKeyRsa());

            SensitiveCreate sensCreate = new SensitiveCreate(new byte[] { 1, 2, 3 }, null);
            CreationData    keyCreationData;
            TkCreation      creationTicket;

            byte[] creationHash;

            Console.WriteLine("Automatic authorization of a primary storage key.");

            //
            // An auth session is added automatically to authorize access to primHandle.
            //
            TpmPrivate keyPrivate = tpm.Create(primHandle,
                                               sensCreate,
                                               keyInPublic,
                                               null,
                                               new PcrSelection[0],
                                               out keyPublic,
                                               out keyCreationData,
                                               out creationHash,
                                               out creationTicket);

            TpmHandle keyHandle = null;

            Console.WriteLine("Strict mode.");

            //
            // Switch TPM object to the strict mode. (Note that this is a TSS.Net
            // specific piece of functionality, not a part of TPM 2.0 specification).
            //
            tpm._Behavior.Strict = true;

            //
            // No auth session is added automatically when TPM object is in strict mode.
            //
            tpm._ExpectError(TpmRc.AuthMissing)
            .Load(primHandle, keyPrivate, keyPublic);

            //
            // Now explicitly request an auth session of a desired type.
            // The actual auth value will be supplied by TSS.Net implicitly.
            //
            keyHandle = tpm[Auth.Default].Load(primHandle, keyPrivate, keyPublic);

            Console.WriteLine("Signing decryption key created.");

            //
            // Switch TPM object back to the normal mode.
            //
            tpm._Behavior.Strict = false;

            return(keyHandle);
        }