Beispiel #1
0
    internal void SetPersistedUri(string uri)
    {
        TpmHandle    nvHandle    = new TpmHandle(PERSISTED_URI_INDEX + logicalDeviceId);
        TpmHandle    ownerHandle = new TpmHandle(TpmRh.Owner);
        UTF8Encoding utf8        = new UTF8Encoding();

        byte[] nvData = utf8.GetBytes(uri);

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

        tpmDevice.Connect();
        using (var tpm = new Tpm2(tpmDevice))
        {
            // Define the store
            tpm.NvDefineSpace(ownerHandle,
                              Array.Empty <byte>(),
                              new NvPublic(nvHandle,
                                           TpmAlgId.Sha256,
                                           NvAttr.Authwrite | NvAttr.Authread | NvAttr.NoDa,
                                           Array.Empty <byte>(),
                                           (ushort)nvData.Length));

            // Write the store
            tpm.NvWrite(nvHandle, nvHandle, nvData, 0);
        }
    }
Beispiel #2
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);
        }
Beispiel #3
0
        internal static void NVReadWrite(Tpm2 tpm)
        {
            //
            // 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();
            TpmHandle nvHandle  = TpmHandle.NV(3001);

            //
            // Clean up any slot that was left over from an earlier run
            //
            tpm._AllowErrors()
            .NvUndefineSpace(TpmRh.Owner, nvHandle);

            //
            // Scenario 1 - write and read a 32-byte NV-slot
            //
            AuthValue nvAuth = AuthValue.FromRandom(8);

            tpm.NvDefineSpace(TpmRh.Owner, nvAuth,
                              new NvPublic(nvHandle, TpmAlgId.Sha1,
                                           NvAttr.Authread | NvAttr.Authwrite,
                                           null, 32));

            //
            // Write some data
            //
            var nvData = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7 };

            tpm.NvWrite(nvHandle, nvHandle, nvData, 0);

            //
            // And read it back
            //
            byte[] nvRead = tpm.NvRead(nvHandle, nvHandle, (ushort)nvData.Length, 0);

            //
            // Is it correct?
            //
            bool correct = nvData.SequenceEqual(nvRead);

            if (!correct)
            {
                throw new Exception("NV data was incorrect.");
            }

            Console.WriteLine("NV data written and read.");

            //
            // And clean up
            //
            tpm.NvUndefineSpace(TpmRh.Owner, nvHandle);
        }
Beispiel #4
0
 // Makes sure that the size of data transferred in a single write operation
 // does not exceed the limit on a command parameter size.
 public static void SafeNvWrite(Tpm2 tpm, ushort maxNvOpSize,
                                TpmHandle nvHandle, byte[] contents)
 {
     for (ushort offset = 0; offset < contents.Length; offset += maxNvOpSize)
     {
         var chunkSize = contents.Length - offset < maxNvOpSize ?
                         contents.Length - offset : maxNvOpSize;
         var data = Globs.CopyData(contents, offset, chunkSize);
         tpm.NvWrite(nvHandle, nvHandle, data, offset);
     }
 }
        private void ProvisionUri(string hostName, string deviceId = "")
        {
            TpmHandle    nvHandle    = new TpmHandle(AIOTH_PERSISTED_URI_INDEX);
            TpmHandle    ownerHandle = new TpmHandle(TpmRh.Owner);
            UTF8Encoding utf8        = new UTF8Encoding();

            byte[] nvData = utf8.GetBytes(hostName + "/" + deviceId);

            // Define the store
            _tpm2.NvDefineSpace(ownerHandle,
                                Array.Empty <byte>(),
                                new NvPublic(nvHandle,
                                             TpmAlgId.Sha256,
                                             NvAttr.Authwrite | NvAttr.Authread | NvAttr.NoDa,
                                             Array.Empty <byte>(),
                                             (ushort)nvData.Length));

            // Write the store
            _tpm2.NvWrite(nvHandle, nvHandle, nvData, 0);
        }
        public void TestTpmCollector()
        {
            var PcrAlgorithm = TpmAlgId.Sha256;

            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                var process = TpmSim.GetTpmSimulator();
                process.Start();

                var  nvData  = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7 };
                uint nvIndex = 3001;

                var tpmc = new TpmCollector(new CollectorOptions()
                {
                    Verbose = true
                }, null, TestMode: true);
                // Prepare to write to NV 3001
                TpmHandle nvHandle = TpmHandle.NV(nvIndex);

                TcpTpmDevice tcpTpmDevice = new TcpTpmDevice("127.0.0.1", 2321, stopTpm: false);
                tcpTpmDevice.Connect();

                using var tpm = new Tpm2(tcpTpmDevice);
                tcpTpmDevice.PowerCycle();
                tpm.Startup(Su.Clear);

                try
                {
                    tpm._AllowErrors()
                    .NvUndefineSpace(TpmRh.Owner, nvHandle);

                    tpm.NvDefineSpace(TpmRh.Owner, null,
                                      new NvPublic(nvHandle, TpmAlgId.Sha1,
                                                   NvAttr.NoDa | NvAttr.Ownerread | NvAttr.Ownerwrite,
                                                   null, 32));

                    // Write to NV 3001
                    tpm.NvWrite(TpmRh.Owner, nvHandle, nvData, 0);

                    var nvOut = tpm.NvRead(TpmRh.Owner, nvHandle, (ushort)nvData.Length, 0);

                    Assert.IsTrue(nvOut.SequenceEqual(nvData));
                }
                catch (TpmException e)
                {
                    Log.Debug(e, "Failed to Write to NV.");
                    Assert.Fail();
                }

                // Verify that all the PCRs are blank to start with
                var pcrs = TpmCollector.DumpPCRs(tpm, PcrAlgorithm, new PcrSelection[] { new PcrSelection(PcrAlgorithm, new uint[] { 15, 16 }) });
                Assert.IsTrue(pcrs.All(x => x.Value.SequenceEqual(new byte[x.Value.Length])));

                // Measure to PCR 16
                try
                {
                    tpm.PcrExtend(TpmHandle.Pcr(16), tpm.PcrEvent(TpmHandle.Pcr(16), nvData));
                }
                catch (TpmException e)
                {
                    Log.Debug(e, "Failed to Write PCR.");
                }

                // Verify that we extended the PCR
                var pcrs2 = TpmCollector.DumpPCRs(tpm, PcrAlgorithm, new PcrSelection[] { new PcrSelection(PcrAlgorithm, new uint[] { 15, 16 }, 24) });
                Assert.IsTrue(pcrs2[(PcrAlgorithm, 15)].SequenceEqual(pcrs[(PcrAlgorithm, 15)]));
Beispiel #7
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);
        }