Esempio n. 1
0
        public TpmHandle GenerateRSASigningKeyPair(AuthValue ownerAuth, out TpmPublic keyPublic, byte[] keyAuth, TpmHandle persistantHandle)
        {
            var keyTemplate = new TpmPublic(TpmAlgId.Sha1,                                      // Name algorithm
                                            ObjectAttr.UserWithAuth | ObjectAttr.Sign |         // Signing key
                                            ObjectAttr.FixedParent | ObjectAttr.FixedTPM |      // Non-migratable
                                            ObjectAttr.SensitiveDataOrigin,
                                            new byte[0],                                        // no policy
                                            new RsaParms(new SymDefObject(),                    // not a restricted decryption key
                                                         new SchemeRsassa(TpmAlgId.Sha1),       // an unrestricted signing key
                                                         2048,
                                                         0),
                                            new Tpm2bPublicKeyRsa());

            var sensCreate = new SensitiveCreate(keyAuth, new byte[0]);

            //TpmPublic keyPublic;

            byte[] outsideInfo      = Globs.GetRandomBytes(8);
            var    creationPcrArray = new PcrSelection[0];

            TpmHandle h = tpm[ownerAuth].CreatePrimary(
                TpmHandle.RhOwner,                          // In the owner-hierarchy
                sensCreate,                                 // With this auth-value
                keyTemplate,                                // Describes key
                outsideInfo,                                // For creation ticket
                creationPcrArray,                           // For creation ticket
                out keyPublic,                              // Out pubKey and attributes
                out CreationData creationData,              // Not used here
                out byte[] creationHash,                    // Not used here
                out TkCreation creationTicket);

            tpm.EvictControl(TpmHandle.RhOwner, h, persistantHandle);

            return(h);
        }
Esempio n. 2
0
        internal static TpmHandle CreateEncryptionDecryptionKey(Tpm2 tpm, TpmHandle parent)
        {
            var sensCreate = new SensitiveCreate(null, null);

            var sym = new SymDefObject(TpmAlgId.Aes, 128, TpmAlgId.Cfb);

            var pub = new TpmPublic(TpmAlgId.Sha256,
                                    ObjectAttr.Decrypt | ObjectAttr.UserWithAuth,
                                    null,
                                    sym,
                                    new Tpm2bDigestSymcipher());

            TssObject swKey = TssObject.Create(pub);


            var innerWrapKey = sym == null ? null : SymCipher.Create(sym);



            byte[]    name, qname;
            TpmPublic pubParent = tpm.ReadPublic(parent, out name, out qname);

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

            TpmPrivate privImp = tpm.Import(parent, innerWrapKey, swKey.Public, dupBlob,
                                            encSecret, sym ?? new SymDefObject());

            TpmHandle hKey = tpm.Load(parent, privImp, swKey.Public)
                             .SetAuth(swKey.Sensitive.authValue);

            return(hKey);
        }
Esempio n. 3
0
        internal static TpmHandle CreatePrimary(Tpm2 tpm, out TpmPublic newKeyPub, byte[] auth = null, byte[] seed = null)
        {
            var sensCreate = new SensitiveCreate(auth, null);

            var parms = new TpmPublic(TpmAlgId.Sha256,                               // Name algorithm
                                      ObjectAttr.Restricted | ObjectAttr.Decrypt |   // Storage key
                                      ObjectAttr.FixedParent | ObjectAttr.FixedTPM | // Non-duplicable
                                      ObjectAttr.UserWithAuth | ObjectAttr.SensitiveDataOrigin,
                                      null,                                          // No policy
                                                                                     // No signing or decryption scheme, and non-empty symmetric
                                                                                     // specification (even when it is an asymmetric key)
                                      new RsaParms(new SymDefObject(TpmAlgId.Aes, 128, TpmAlgId.Cfb),
                                                   null, 2048, 0),
                                      new Tpm2bPublicKeyRsa(seed) // Additional entropy for key derivation
                                      );

            CreationData creationData;
            TkCreation   creationTicket;

            byte[] creationHash;

            var handle = tpm.CreatePrimary(TpmRh.Owner,           // In storage hierarchy
                                           sensCreate,            // Auth value
                                           CreateDecryptionKey(), // Key template
                                                                  //
                                                                  // The following parameters influence the creation of the
                                                                  // creation-ticket. They are not used in this sample
                                                                  //
                                           null,                  // Null outsideInfo
                                           new PcrSelection[0],   // Not PCR-bound
                                           out newKeyPub,         // Our outs
                                           out creationData, out creationHash, out creationTicket);

            return(handle);
        }
Esempio n. 4
0
        } // SimpleDuplicateImportRsaSample

        TssObject ImportExternalRsaKey(Tpm2 tpm, TpmHandle hParent,
                                       int keySizeInBits, IAsymSchemeUnion scheme,
                                       byte[] publicPart, byte[] privatePart,
                                       ObjectAttr keyAttrs,
                                       byte[] authVal = null, byte[] policyDigest = null)
        {
            TpmAlgId sigHashAlg = TpmHelper.GetSchemeHash(scheme),
                     nameAlg    = sigHashAlg;

            // TPM signing key template with the actual public key bits
            var inPub = new TpmPublic(nameAlg,
                                      keyAttrs,
                                      policyDigest,
                                      new RsaParms(new SymDefObject(), scheme as IAsymSchemeUnion,
                                                   (ushort)keySizeInBits, 0),
                                      new Tpm2bPublicKeyRsa(publicPart));

            // Wrap the key in a TSS helper class
            TssObject swKey = TssObject.Create(inPub, authVal, privatePart);

            // Get a key duplication blob in TPM 2.0 compatibale format
            TpmPrivate dupBlob = swKey.GetPlaintextDuplicationBlob();

            // Importing a duplication blob creates a new TPM private key blob protected
            // with its new parent key.
            swKey.Private = tpm.Import(hParent, null, swKey.Public, dupBlob, null, new SymDefObject());

            return(swKey);
        } // ImportExternalRsaKey
Esempio n. 5
0
        private TpmPublic ReadOrCreatePersistedKey(TpmHandle persHandle, TpmHandle hierarchy, TpmPublic template)
        {
            byte[] name;
            byte[] qualifiedName;

            // Let's see if the key was already created and installed.
            TpmPublic keyPub = _tpm2._AllowErrors().ReadPublic(persHandle, out name, out qualifiedName);

            // If not create and install it.
            if (!_tpm2._LastCommandSucceeded())
            {
                CreationData creationData;
                byte[]       creationHash;
                TkCreation   creationTicket;
                TpmHandle    keyHandle = _tpm2.CreatePrimary(hierarchy,
                                                             new SensitiveCreate(),
                                                             template,
                                                             Array.Empty <byte>(),
                                                             Array.Empty <PcrSelection>(),
                                                             out keyPub,
                                                             out creationData,
                                                             out creationHash,
                                                             out creationTicket);
                _tpm2.EvictControl(TpmHandle.RhOwner, keyHandle, persHandle);
                _tpm2.FlushContext(keyHandle);
            }
            return(keyPub);
        }
Esempio n. 6
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));
        }
Esempio n. 7
0
    /// <summary>
    /// Gets the identifier of the device
    /// </summary>
    /// <returns></returns>
    public string GetHardwareDeviceId()
    {
        TpmHandle srkHandle = new TpmHandle(TPM_20_SRK_HANDLE);

        try
        {
            string hardwareDeviceId;

            // Open the TPM
            Tpm2Device tpmDevice = new TbsDevice();
            tpmDevice.Connect();
            using (var tpm = new Tpm2(tpmDevice))
            {
                // Read the URI from the TPM
                TpmPublic srk = tpm.ReadPublic(srkHandle, out byte[] name, out byte[] qualifiedName);

                // Calculate the hardware device id for this logical device
                byte[] deviceId = CryptoLib.HashData(TpmAlgId.Sha256, BitConverter.GetBytes(logicalDeviceId), name);

                // Produce the output string
                hardwareDeviceId = string.Join(string.Empty, deviceId.Select(b => b.ToString("x2")));
            }

            return(hardwareDeviceId);
        }
        catch { }

        return(string.Empty);
    }
Esempio n. 8
0
        void DuplicateImportRsaSample(Tpm2 tpm, TestContext testCtx)
        {
            TpmAlgId nameAlg = Substrate.Random(TpmCfg.HashAlgs);
            var      policy  = new PolicyTree(nameAlg);

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

            var inPub = new TpmPublic(nameAlg,
                                      ObjectAttr.Sign | ObjectAttr.AdminWithPolicy | ObjectAttr.SensitiveDataOrigin,
                                      policy.GetPolicyDigest(),
                                      new RsaParms(new SymDefObject(),
                                                   new SchemeRsassa(Substrate.Random(TpmCfg.HashAlgs)),
                                                   Substrate.Random(TpmCfg.RsaKeySizes), 0),
                                      new Tpm2bPublicKeyRsa());

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

            // Duplicate
            TpmPrivate priv = TpmHelper.GetPlaintextPrivate(tpm, hKey, policy);

            tpm.FlushContext(hKey);

            // Import
            TpmPrivate privImp = tpm.Import(Substrate.LoadRsaPrimary(tpm), null, pub, priv, null, new SymDefObject());
        } // SimpleDuplicateImportRsaSample
Esempio n. 9
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
Esempio n. 10
0
 public static IAsymSchemeUnion GetScheme(TpmPublic pub)
 {
     return(pub.type == TpmAlgId.Keyedhash
                 ? (IAsymSchemeUnion)(pub.parameters as KeyedhashParms).scheme
                 : pub.type == TpmAlgId.Rsa
                         ? (IAsymSchemeUnion)(pub.parameters as RsaParms).scheme
                         : (IAsymSchemeUnion)(pub.parameters as EccParms).scheme);
 }
Esempio n. 11
0
        static TpmHandle CreateRsaPrimaryKey(Tpm2 tpm, bool isSimulator)
        {
            if (isSimulator)
            {
                tpm.DictionaryAttackParameters(TpmHandle.RhLockout, 1000, 10, 1);
                tpm.DictionaryAttackLockReset(TpmHandle.RhLockout);
            }

            //
            // First member of SensitiveCreate contains auth value of the key
            //
            var sensCreate = new SensitiveCreate(new byte[] { 0xa, 0xb, 0xc }, null);

            TpmPublic parms = new TpmPublic(
                TpmAlgId.Sha1,
                ObjectAttr.Restricted | ObjectAttr.Decrypt | ObjectAttr.FixedParent | ObjectAttr.FixedTPM
                | ObjectAttr.UserWithAuth | ObjectAttr.SensitiveDataOrigin,
                null,
                new RsaParms(
                    new SymDefObject(TpmAlgId.Aes, 128, TpmAlgId.Cfb),
                    new NullAsymScheme(),
                    2048,
                    0),
                new Tpm2bPublicKeyRsa());

            byte[] outsideInfo = Globs.GetRandomBytes(8);
            var    creationPcr = new PcrSelection(TpmAlgId.Sha1, new uint[] { 0, 1, 2 });

            TpmPublic    pubCreated;
            CreationData creationData;
            TkCreation   creationTicket;

            byte[] creationHash;

            Console.WriteLine("Automatic authorization of TpmRh.Owner.");

            //
            // An auth session is added automatically to authorize access to the permanent
            // handle TpmHandle.RhOwner.
            //
            // Note that if the TPM is not a simulator and not cleared, you need to
            // assign the corresponding auth value to the tpm.OwnerAuth property of
            // the given Tpm2 object.
            //
            TpmHandle h = tpm.CreatePrimary(TpmRh.Owner,
                                            sensCreate,
                                            parms,
                                            outsideInfo,
                                            new PcrSelection[] { creationPcr },
                                            out pubCreated,
                                            out creationData,
                                            out creationHash,
                                            out creationTicket);

            Console.WriteLine("Primary RSA storage key created.");

            return(h);
        }
Esempio n. 12
0
        internal static TpmPublic CreateDecryptionKey2()
        {
            var pub = new TpmPublic(TpmAlgId.Sha1,
                                    ObjectAttr.Decrypt | ObjectAttr.UserWithAuth | ObjectAttr.SensitiveDataOrigin,
                                    null,
                                    new RsaParms(null, new SchemeOaep(TpmAlgId.Sha1), 2048, 0),
                                    new Tpm2bPublicKeyRsa());

            return(pub);
        }
Esempio n. 13
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
Esempio n. 14
0
        void EcdhSample(Tpm2 tpm, TestContext testCtx)
        {
            //
            // Peer A (e.g. local machine):
            //

            // Template for an ECC key with the ECDH scheme:
            var inPub = new TpmPublic(TpmAlgId.Sha256,
                                      ObjectAttr.Decrypt | ObjectAttr.UserWithAuth | ObjectAttr.SensitiveDataOrigin,
                                      null,
                                      new EccParms(new SymDefObject(), new SchemeEcdh(TpmAlgId.Sha256),
                                                   EccCurve.NistP256, new NullKdfScheme()),
                                      new EccPoint());

            // Boilerplate stuff
            var          pcrSel = new PcrSelection[0];
            CreationData crData;

            byte[]     crHash;
            TkCreation crTk;

            // Create a key for ECDH
            TpmPublic pubA;
            TpmHandle hKeyA = tpm.CreatePrimary(TpmRh.Owner, new SensitiveCreate(), inPub, null, new PcrSelection[0],
                                                out pubA, out crData, out crHash, out crTk);

            //
            // Peer B (e.g. remote machine):
            //

            // Receives 'pubA' from peer A

            // Load public key
            TpmHandle hPubKeyA = tpm.LoadExternal(null, pubA, TpmRh.Owner);

            // Create shared secret 'zB', and a public ECC point for exchange
            EccPoint ephPubPt;
            EccPoint zB = tpm.EcdhKeyGen(hPubKeyA, out ephPubPt);

            tpm.FlushContext(hPubKeyA);

            //
            // Peer A again:
            //

            // Receives 'ephPubPt' from peer B

            // A full key is required here
            EccPoint zA = tpm.EcdhZGen(hKeyA, ephPubPt);

            testCtx.AssertEqual("SharedSecret", zA, zB);

            tpm.FlushContext(hKeyA);
        } // EcdhSample
Esempio n. 15
0
        internal static TpmPublic CreateDecryptionKey()
        {
            var sym = new SymDefObject(TpmAlgId.Aes, 128, TpmAlgId.Cfb);

            var pub = new TpmPublic(TpmAlgId.Sha256,
                                    ObjectAttr.Decrypt | ObjectAttr.UserWithAuth,
                                    null,
                                    new SymDefObject(TpmAlgId.Aes, 128, TpmAlgId.Cfb),
                                    new Tpm2bDigestSymcipher());

            return(pub);
        }
Esempio n. 16
0
        /// <summary>
        /// Create a sealed-object primary that can be accessed with the given policy. SHA256 is assumed.
        /// </summary>
        /// <param name="tpm"></param>
        /// <param name="dataToSeal"></param>
        /// <param name="authValue"></param>
        /// <param name="policy"></param>
        /// <returns></returns>
        private static TpmHandle CreateSealedPrimaryObject(Tpm2 tpm, byte[] dataToSeal, byte[] authValue, byte[] policy)
        {
            ObjectAttr attrs = ObjectAttr.FixedTPM | ObjectAttr.FixedParent;

            if (authValue != null)
            {
                attrs |= ObjectAttr.UserWithAuth;
            }

            byte[] policyVal      = policy ?? new byte[0];
            var    sealedInPublic = new TpmPublic(TpmAlgId.Sha256,
                                                  attrs,
                                                  policyVal,
                                                  new KeyedhashParms(new NullSchemeKeyedhash()),
                                                  new Tpm2bDigestKeyedhash());

            //
            // Envelope for sealed data and auth
            //
            byte[] authVal           = authValue ?? new byte[0];
            var    sealedInSensitive = new SensitiveCreate(authVal, dataToSeal);

            TkCreation creationTicket;

            byte[]       creationHashSealed;
            TpmPublic    sealedPublic;
            CreationData sealedCreationData;

            //
            // 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();

            //
            // Ask the TPM to create a primary containing the "sealed" data
            //
            TpmHandle primHandle = tpm[ownerAuth].CreatePrimary(TpmHandle.RhOwner,
                                                                sealedInSensitive,
                                                                sealedInPublic,
                                                                new byte[0],
                                                                new PcrSelection[0],
                                                                out sealedPublic,
                                                                out sealedCreationData,
                                                                out creationHashSealed,
                                                                out creationTicket);

            return(primHandle);
        }
Esempio n. 17
0
 public static byte[] GetUniqueBuffer(TpmPublic pub)
 {
     byte[] buf;
     if (pub.parameters.GetUnionSelector() == TpmAlgId.Ecc)
     {
         buf = (pub.unique as EccPoint).GetTpmRepresentation();
     }
     else
     {
         GetUniqueBuffer(pub, out buf);
     }
     return(buf);
 }
        // Constructor helpers
        private void CacheEkAndSrk()
        {
            ObjectAttr ekObjectAttributes =
                ObjectAttr.FixedTPM | ObjectAttr.FixedParent | ObjectAttr.SensitiveDataOrigin |
                ObjectAttr.AdminWithPolicy | ObjectAttr.Restricted | ObjectAttr.Decrypt;

            var ekAuthPolicy = new byte[]
            {
                0x83, 0x71, 0x97, 0x67, 0x44, 0x84, 0xb3, 0xf8,
                0x1a, 0x90, 0xcc, 0x8d, 0x46, 0xa5, 0xd7, 0x24,
                0xfd, 0x52, 0xd7, 0x6e, 0x06, 0x52, 0x0b, 0x64,
                0xf2, 0xa1, 0xda, 0x1b, 0x33, 0x14, 0x69, 0xaa
            };

            // Get the real EK ready
            TpmPublic ekTemplate = new TpmPublic(
                TpmAlgId.Sha256,
                ekObjectAttributes,
                ekAuthPolicy,
                new RsaParms(new SymDefObject(TpmAlgId.Aes, 128, TpmAlgId.Cfb),
                             new NullAsymScheme(),
                             2048,
                             0),
                new Tpm2bPublicKeyRsa(new Byte[2048 / 8]));

            _ekPub = ReadOrCreatePersistedKey(
                new TpmHandle(TPM_20_EK_HANDLE),
                new TpmHandle(TpmHandle.RhEndorsement),
                ekTemplate);

            ObjectAttr srkObjectAttributes =
                ObjectAttr.FixedTPM | ObjectAttr.FixedParent | ObjectAttr.SensitiveDataOrigin |
                ObjectAttr.UserWithAuth | ObjectAttr.NoDA | ObjectAttr.Restricted | ObjectAttr.Decrypt;

            // Get the real SRK ready
            TpmPublic srkTemplate = new TpmPublic(
                TpmAlgId.Sha256,
                srkObjectAttributes,
                Array.Empty <byte>(),
                new RsaParms(new SymDefObject(TpmAlgId.Aes, 128, TpmAlgId.Cfb),
                             new NullAsymScheme(),
                             2048,
                             0),
                new Tpm2bPublicKeyRsa(new Byte[2048 / 8]));

            _srkPub = ReadOrCreatePersistedKey(
                new TpmHandle(TPM_20_SRK_HANDLE),
                new TpmHandle(TpmHandle.RhOwner),
                srkTemplate);
        }
Esempio n. 19
0
        } // CreateRsaPrimaryStorageKey()

        /// <summary>
        /// Main logic of the Import sample.
        /// The sample demonstrates how to create in software (using TSS.net helpers)
        /// keys of different kinds, then import them into TPM and make sure they work.
        /// </summary>
        static void ImportSample(Tpm2 tpm)
        {
            // Templates of the keys to be generated and imported
            var inPubs = new TpmPublic[] {
                new TpmPublic(TpmAlgId.Sha256,
                              ObjectAttr.Decrypt | ObjectAttr.UserWithAuth,
                              null,
                              new SymDefObject(TpmAlgId.Aes, 128, TpmAlgId.Cfb),
                              new Tpm2bDigestSymcipher()),
                new TpmPublic(TpmAlgId.Sha256,
                              ObjectAttr.Sign | ObjectAttr.UserWithAuth,
                              null,
                              new RsaParms(new SymDefObject(),
                                           new SchemeRsassa(TpmAlgId.Sha256),
                                           2048, 0),
                              new Tpm2bPublicKeyRsa()),
                new TpmPublic(TpmAlgId.Sha256,
                              ObjectAttr.Sign | ObjectAttr.UserWithAuth,
                              null,
                              new KeyedhashParms(new SchemeHmac(TpmAlgId.Sha256)),
                              new Tpm2bDigestKeyedhash())
            };

            // Create a TPM based key that will serve as a parent for the imported keys.
            // This should be a storage key, i.e. it must have Restricted and Decrypt
            // attributes, no signing or decryption scheme, and non-empty symmetric
            // specification (even if it is an asymmetric key) as part of its parameters.
            // NOTE 1 - We use an empty auth value for the parent key. If you want one,
            // uncomment the optional second parameter.
            // NOTE 2 - The size of the auth value shall not exceed the size of the digest
            // produced by the name algorithm of the key. In this case name algorithm is
            // hardcoded inside the helper, so that we do not have control over it at
            // this point, and therefore we use the maximal number that is safe for any
            // modern hash algorithm (SHA-1 or larger), though for the given implementation
            // of CreateRsaPrimaryStorageKey() we could use 32 (for SHA-256).
            TpmHandle hPrim = CreateRsaPrimaryStorageKey(tpm /*, AuthValue.FromRandom(20)*/);

            foreach (var inPub in inPubs)
            {
                GenerateAndImport(tpm, inPub, hPrim);

                // Now do the same using an inner wrapper (additional layer of cryptographic
                // protection in the form of symmetric encryption for the duplication blob).
                GenerateAndImport(tpm, inPub, hPrim,
                                  new SymDefObject(TpmAlgId.Aes, 128, TpmAlgId.Cfb));
            }

            tpm.FlushContext(hPrim);
        } // ImportSample()
Esempio n. 20
0
        void TestCertifyX509(Tpm2 tpm, TestContext testCtx)
        {
            if (!TpmCfg.IsImplemented(TpmCc.CertifyX509))
            {
                Substrate.WriteToLog("TestCertifyX509 skipped", ConsoleColor.DarkCyan);
                return;
            }

            ObjectAttr attr = ObjectAttr.Restricted | ObjectAttr.Sign
                              | ObjectAttr.FixedParent | ObjectAttr.FixedTPM
                              | ObjectAttr.UserWithAuth | ObjectAttr.AdminWithPolicy
                              | ObjectAttr.SensitiveDataOrigin;

            var policy = new PolicyTree(TpmAlgId.Sha256);

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

            var keyTemplateRsa = new TpmPublic(TpmAlgId.Sha256, attr, policy.GetPolicyDigest(),
                                               new RsaParms(new SymDefObject(), new SchemeRsassa(TpmAlgId.Sha256), 2048, 0),
                                               new Tpm2bPublicKeyRsa()
                                               );
            var keyTemplateEcc = new TpmPublic(TpmAlgId.Sha256, attr, policy.GetPolicyDigest(),
                                               new EccParms(new SymDefObject(), new SchemeEcdsa(TpmAlgId.Sha256),
                                                            EccCurve.NistP256, new NullKdfScheme()),
                                               new EccPoint()
                                               );
            var keyTemplatePss = new TpmPublic(TpmAlgId.Sha256, attr, policy.GetPolicyDigest(),
                                               new RsaParms(new SymDefObject(), new SchemeRsapss(TpmAlgId.Sha256), 2048, 0),
                                               new Tpm2bPublicKeyRsa()
                                               );

            TestCertifyX509Impl(tpm, testCtx, keyTemplateRsa, keyTemplateRsa, policy, "RsaWithRsa.1");
            TestCertifyX509Impl(tpm, testCtx, keyTemplateRsa, keyTemplateEcc, policy, "RsaWithEcc.1");
            TestCertifyX509Impl(tpm, testCtx, keyTemplateEcc, keyTemplateEcc, policy, "EccWithEcc.1");
            TestCertifyX509Impl(tpm, testCtx, keyTemplateEcc, keyTemplateRsa, policy, "EccWithRsa.1");
            TestCertifyX509Impl(tpm, testCtx, keyTemplateRsa, keyTemplatePss, policy, "RsaWithPss.1");
            TestCertifyX509Impl(tpm, testCtx, keyTemplateEcc, keyTemplatePss, policy, "EccWithPss.1");

            attr &= ~(ObjectAttr.Restricted | ObjectAttr.FixedParent | ObjectAttr.FixedTPM);
            keyTemplateRsa.objectAttributes = attr;
            keyTemplateEcc.objectAttributes = attr;
            keyTemplatePss.objectAttributes = attr;
            TestCertifyX509Impl(tpm, testCtx, keyTemplateRsa, keyTemplateRsa, policy, "RsaWithRsa.2");
            TestCertifyX509Impl(tpm, testCtx, keyTemplateRsa, keyTemplateEcc, policy, "RsaWithEcc.2");
            TestCertifyX509Impl(tpm, testCtx, keyTemplateEcc, keyTemplateEcc, policy, "EccWithEcc.2");
            TestCertifyX509Impl(tpm, testCtx, keyTemplateEcc, keyTemplateRsa, policy, "EccWithRsa.2");
            TestCertifyX509Impl(tpm, testCtx, keyTemplateRsa, keyTemplatePss, policy, "RsaWithPss.2");
            TestCertifyX509Impl(tpm, testCtx, keyTemplateEcc, keyTemplatePss, policy, "EccWithPss.2");
        } // TestCertifyX509
        private void CacheEkAndSrk()
        {
            if (Logging.IsEnabled)
            {
                Logging.Enter(this, null, nameof(CacheEkAndSrk));
            }

            // Get the real EK ready.
            var ekTemplate = new TpmPublic(
                TpmAlgId.Sha256,
                ObjectAttr.FixedTPM | ObjectAttr.FixedParent | ObjectAttr.SensitiveDataOrigin |
                ObjectAttr.AdminWithPolicy | ObjectAttr.Restricted | ObjectAttr.Decrypt,
                new byte[]
            {
                0x83, 0x71, 0x97, 0x67, 0x44, 0x84, 0xb3, 0xf8, 0x1a, 0x90, 0xcc, 0x8d, 0x46, 0xa5, 0xd7, 0x24,
                0xfd, 0x52, 0xd7, 0x6e, 0x06, 0x52, 0x0b, 0x64, 0xf2, 0xa1, 0xda, 0x1b, 0x33, 0x14, 0x69, 0xaa
            },
                new RsaParms(
                    new SymDefObject(TpmAlgId.Aes, 128, TpmAlgId.Cfb),
                    new NullAsymScheme(),
                    2048,
                    0),
                new Tpm2bPublicKeyRsa(new byte[2048 / 8]));

            _ekPub = ReadOrCreatePersistedKey(new TpmHandle(Tpm20EkHandle), new TpmHandle(TpmHandle.RhEndorsement), ekTemplate);

            // Get the real SRK ready.
            var srkTemplate = new TpmPublic(
                TpmAlgId.Sha256,
                ObjectAttr.FixedTPM | ObjectAttr.FixedParent | ObjectAttr.SensitiveDataOrigin |
                ObjectAttr.UserWithAuth | ObjectAttr.NoDA | ObjectAttr.Restricted | ObjectAttr.Decrypt,
                Array.Empty <byte>(),
                new RsaParms(
                    new SymDefObject(TpmAlgId.Aes, 128, TpmAlgId.Cfb),
                    new NullAsymScheme(),
                    2048,
                    0),
                new Tpm2bPublicKeyRsa(new byte[2048 / 8]));

            _srkPub = ReadOrCreatePersistedKey(new TpmHandle(Tpm20SrkHandle), new TpmHandle(TpmHandle.RhOwner), srkTemplate);

            if (Logging.IsEnabled)
            {
                Logging.Exit(this, null, nameof(CacheEkAndSrk));
            }
        }
Esempio n. 22
0
        /// <summary>
        /// Create an RSA primary storage key in the storage hierarchy and return the key-handle
        /// to the caller.  The key will be RSA2048 with a SHA256-name algorithm.  The caller can
        /// provide user-auth. The caller is responsible for disposing of this key.
        /// </summary>
        /// <returns></returns>
        static TpmHandle CreateRsaPrimaryStorageKey(Tpm2 tpm, byte[] auth, out TpmPublic newKeyPub)
        {
            //
            // Creation parameters (no external data for TPM-created objects)
            //
            var sensCreate = new SensitiveCreate(auth,         // Auth-data provided by the caller
                                                 new byte[0]); // No external data (the TPM will create the new key).

            var parms = new TpmPublic(TpmAlgId.Sha256,
                                      ObjectAttr.Restricted | ObjectAttr.Decrypt |   // Storage key
                                      ObjectAttr.FixedParent | ObjectAttr.FixedTPM | // Non-duplicable
                                      ObjectAttr.UserWithAuth | ObjectAttr.SensitiveDataOrigin,
                                      new byte[0],                                   // No policy, and Storage key should be RSA + AES128
                                      new RsaParms(new SymDefObject(TpmAlgId.Aes, 128, TpmAlgId.Cfb),
                                                   new NullAsymScheme(), 2048, 0),
                                      new Tpm2bPublicKeyRsa());

            //
            // The following are returned by the TPM in CreatePrimary (and Create)
            // they are not used in this sample.
            //
            CreationData creationData;
            TkCreation   creationTicket;

            byte[] creationHash;

            TpmHandle primHandle = tpm[_ownerAuth].CreatePrimary(TpmHandle.RhOwner,   // In storage hierarchy
                                                                 sensCreate,          // UserAuth
                                                                 parms,               // Creation parms set above
                                                                                      //
                                                                                      // The following parameters influence the creation of the
                                                                                      // creation-ticket. They are not used in this sample
                                                                                      //
                                                                 new byte[0],         // Null outsideInfo
                                                                 new PcrSelection[0], // Do not record PCR-state
                                                                 out newKeyPub,       // Our outs
                                                                 out creationData, out creationHash, out creationTicket);

            return(primHandle);
        }
Esempio n. 23
0
        void LoadExternalFullRsaKeySample(Tpm2 tpm, TestContext testCtx)
        {
            var hashAlg = TpmAlgId.Sha256;
            var inPub   = new TpmPublic(hashAlg,
                                        ObjectAttr.Decrypt | ObjectAttr.UserWithAuth | ObjectAttr.SensitiveDataOrigin,
                                        null,
                                        new RsaParms(new SymDefObject(), new SchemeOaep(hashAlg), 2048, 0),
                                        new Tpm2bPublicKeyRsa());

            // Create a software RSA key
            var swKey = new AsymCryptoSystem(inPub);

            // The crucial point in loading a software key is preparing the TPM-formatted private part of the key
            Sensitive sens = swKey.GetSensitive();

            TpmHandle extKey = tpm.LoadExternal(sens, swKey.GetPublicParms(), TpmRh.Null);

            //
            // Make sure that the key was loaded correctly
            //

            // This particular label is used by the TPM while doing OAEP for its internal protocols
            // (though in n general any label can be used).
            byte[] label   = RawRsa.GetLabel("OaepLabel");
            byte[] origMsg = Substrate.RandomBytes(64);

            // Encrypt using software key (the paublic part is used)
            byte[] encMsg = swKey.EncryptOaep(origMsg, label);

            testCtx.AssertNotEqual("SwEnc", origMsg, encMsg);

            // Decrypt using the TPM (the private part is used)
            byte[] decMsg = tpm.RsaDecrypt(extKey, encMsg, null, label);

            testCtx.AssertEqual("CrossEncDec", origMsg, decMsg);

            tpm.FlushContext(extKey);
        }
Esempio n. 24
0
        public TpmHandle GenerateRsaEncryptionKeyPair(AuthValue ownerAuth, out TpmPublic keyPublic, byte[] keyAuth, TpmHandle persistantHandle)
        {
            var sensCreate = new SensitiveCreate(keyAuth, new byte[0]);

            TpmPublic keyTemplate = new TpmPublic(
                TpmAlgId.Sha1,
                ObjectAttr.UserWithAuth | ObjectAttr.Decrypt |
                ObjectAttr.FixedParent | ObjectAttr.FixedTPM |
                ObjectAttr.SensitiveDataOrigin,
                new byte[0],
                new RsaParms(
                    new SymDefObject(),                                 //a unrestricted decryption key
                    new NullAsymScheme(),                               //not a signing key
                    2048,
                    0),
                new Tpm2bPublicKeyRsa());

            byte[] outsideInfo      = Globs.GetRandomBytes(8);
            var    creationPcrArray = new PcrSelection[0];


            TpmHandle h = tpm[ownerAuth].CreatePrimary(
                TpmRh.Owner,
                sensCreate,
                keyTemplate,
                outsideInfo,
                creationPcrArray,
                out keyPublic,
                out CreationData creationData,
                out byte[] creationHash,
                out TkCreation creationTicket);

            tpm.EvictControl(TpmHandle.RhOwner, h, persistantHandle);

            return(h);
        }
Esempio n. 25
0
        // Returns reference to the byte buffer containing unique value of inPub.
        // Note that in case of ECC keys, the returned buffer references only the
        // first half of the unique value (i.e. x-coordinate of the ECC point).
        public static FieldInfo GetUniqueBuffer(TpmPublic pub, out byte[] buf)
        {
            var keyType = pub.parameters.GetUnionSelector();

            buf = null;
            switch (keyType)
            {
            case TpmAlgId.Rsa:
                buf = (pub.unique as Tpm2bPublicKeyRsa).buffer;
                return(pub.unique.GetType().GetField("buffer"));

            case TpmAlgId.Ecc:
                buf = (pub.unique as EccPoint).x;
                return(pub.unique.GetType().GetField("x"));

            case TpmAlgId.Symcipher:
            case TpmAlgId.Keyedhash:
                buf = (pub.unique as Tpm2bDigest).buffer;
                return(pub.unique.GetType().GetField("buffer"));
            }
            Globs.Throw <NotImplementedException>(
                "GetUniqueBuffer: Unknown TpmPublic type " + keyType);
            return(null);
        }
Esempio n. 26
0
        public string GetHardwareDeviceId()
        {
            TpmHandle srkHandle        = new TpmHandle(SRK_HANDLE);
            string    hardwareDeviceId = "";

            Byte[] name;
            Byte[] qualifiedName;

            try
            {
                // Open the TPM
                Tpm2Device tpmDevice = new TbsDevice();
                tpmDevice.Connect();
                var tpm = new Tpm2(tpmDevice);

                // Read the URI from the TPM
                TpmPublic srk = tpm.ReadPublic(srkHandle, out name, out qualifiedName);

                // Dispose of the TPM
                tpm.Dispose();
            }
            catch
            {
                return(hardwareDeviceId);
            }

            // Calculate the hardware device id for this logical device
            byte[] deviceId = CryptoLib.HashData(TpmAlgId.Sha256, BitConverter.GetBytes(logicalDeviceId), name);

            // Produce the output string
            foreach (byte n in deviceId)
            {
                hardwareDeviceId += n.ToString("x2");
            }
            return(hardwareDeviceId);
        }
Esempio n. 27
0
        internal static TpmHandle CreatePrimaryRsaKey(Tpm2 tpm, TpmHandle primHandle, byte[] auth, byte[] seed, out TpmPublic keyPublic)
        {
            if (primHandle == null)
            {
                primHandle = TpmRh.Endorsement;
            }

            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(seed));

            SensitiveCreate sensCreate = new SensitiveCreate(auth, null);

            CreationData keyCreationData;
            TkCreation   creationTicket;

            byte[] creationHash;

            TpmHandle keyPrivate = tpm.CreatePrimary(primHandle,
                                                     sensCreate,
                                                     keyInPublic,
                                                     auth,
                                                     new PcrSelection[0],
                                                     out keyPublic,
                                                     out keyCreationData,
                                                     out creationHash,
                                                     out creationTicket);

            return(keyPrivate);
        }
Esempio n. 28
0
        void ActivateAikSample(Tpm2 tpm, TestContext testCtx)
        {
            // Use an RSA primary key in the Endorsement hierarchy (EK) to 'activate'
            // another primary in the Endorsement hierarchy (AIK).

            // Note: this procedure can be used to activate a key in the Storage hierarchy, too.

            // "Activation" means secure passing sensitive data generated by a CA (e.g.
            // a symmetric key protecting a freshly generated certificate), so that only
            // a device with the TPM owning the target AIK and EK can access these data.

            // Create a primary key that we will certify.

            //////////////////////////////////////////////////////////////////////////////
            // Device side code
            //////////////////////////////////////////////////////////////////////////////

            // Name algorithm of the new AIK
            TpmAlgId nameAlg = TpmAlgId.Sha256;

            // The key to be certified needs a policy. It can be ANY policy, but here
            // it is configured to allow AIK usage only with the following commands
            var policyAIK = new PolicyTree(nameAlg);
            var policyOR  = new TpmPolicyOr();

            policyAIK.SetPolicyRoot(policyOR);
            policyOR.AddPolicyBranch(new TpmPolicyCommand(TpmCc.ActivateCredential, "Activate"));
            policyOR.AddPolicyBranch(new TpmPolicyCommand(TpmCc.Certify, "Certify"));
            policyOR.AddPolicyBranch(new TpmPolicyCommand(TpmCc.CertifyCreation, "CertifyCreation"));
            policyOR.AddPolicyBranch(new TpmPolicyCommand(TpmCc.Quote, "Quote"));

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

            TpmPublic    AIKpub;
            var          inSens = new SensitiveCreate(Substrate.RandomAuth(nameAlg), null);
            CreationData creationData;

            byte[]     creationHash;
            TkCreation creationTk;
            TpmHandle  hAIK = tpm.CreatePrimary(TpmRh.Endorsement, inSens, inAIKPub, null, null, out AIKpub,
                                                out creationData, out creationHash, out creationTk);
            // An alternative using test substrate helper
            //TpmHandle hAIK = Substrate.CreatePrimary(tpm, inAIKPub, TpmRh.Endorsement);

            // Normally a device would have a pre-provisioned persistent EK with the above handle
            TpmHandle hEK = new TpmHandle(0x81010001);

            // Get its public part
            TpmPublic EKpub = null;

            // In a test environment the real EK may be absent. In this case use
            // a primary key temporarily created in the Endorsement hierarchy.
            byte[] name, qname;
            tpm._AllowErrors()
            .ReadPublic(hEK, out name, out qname);
            if (!tpm._LastCommandSucceeded())
            {
                var inEKpub = new TpmPublic(TpmAlgId.Sha256,
                                            ObjectAttr.Restricted | ObjectAttr.Decrypt | ObjectAttr.FixedParent | ObjectAttr.FixedTPM
                                            | ObjectAttr.AdminWithPolicy | ObjectAttr.SensitiveDataOrigin,
                                            new byte[] { 0x83, 0x71, 0x97, 0x67, 0x44, 0x84, 0xb3, 0xf8,
                                                         0x1a, 0x90, 0xcc, 0x8d, 0x46, 0xa5, 0xd7, 0x24,
                                                         0xfd, 0x52, 0xd7, 0x6e, 0x06, 0x52, 0x0b, 0x64,
                                                         0xf2, 0xa1, 0xda, 0x1b, 0x33, 0x14, 0x69, 0xaa },
                                            new RsaParms(new SymDefObject(TpmAlgId.Aes, 128, TpmAlgId.Cfb), null, 2048, 0),
                                            new Tpm2bPublicKeyRsa());

                inSens = new SensitiveCreate(null, null);
                hEK    = tpm.CreatePrimary(TpmRh.Endorsement, inSens, inEKpub, null, null, out EKpub,
                                           out creationData, out creationHash, out creationTk);
            }

            // Marshal public parts of AIK and EK

            byte[] AIKpubBytes = AIKpub.GetTpmRepresentation();
            byte[] EKpubBytes  = EKpub.GetTpmRepresentation();

            // Here the device uses network to pass AIKpubBytes and EKpubBytes (as well as
            // the EK certificate) to CA service.


            //////////////////////////////////////////////////////////////////////////////
            // Service (CA) side code
            //////////////////////////////////////////////////////////////////////////////

            // Unmarshal AIKpub and EKpub (and EK certificate)

            var m = new Marshaller(AIKpubBytes);

            AIKpub = m.Get <TpmPublic>();
            m      = new Marshaller(EKpubBytes);
            EKpub  = m.Get <TpmPublic>();

            // Symmetric key to be used by CA to encrypt the new certificate it creates for AIK
            byte[] secretKey = Substrate.RandomBytes(32);

            // Here CA does the following (the sample does not show this code):
            // - Validates EK certificate
            // - Generates a new certificate for AIK (AIKcert)
            // - Encrypts AIKcert with secretKey

            // Create an activation blob

            // Internal wrapper key encrypted with EKpub to be used by TPM2_ActivateCredential() command.
            byte[] encSecret;

            // An encrypted and HMACed object tied to the destination TPM. It contains
            // 'secret' to be extracted by the successful TPM2_ActivateCredential() command
            // (that can only succeeed on the TPM that originated both EK and AIK).
            IdObject certInfo;

            // Run TSS.Net equivalent of TPM2_MakeCredential() command (convenient for the server side,
            // as it will likely be faster than the TPM transaction and allows concurrent execution).
            certInfo = EKpub.CreateActivationCredentials(secretKey, AIKpub.GetName(), out encSecret);

            // Marshal certInfo

            // IdObject data type requires customized marshaling
            m = new Marshaller();
            m.Put(certInfo.integrityHMAC.Length, "integrityHMAC.Length");
            m.Put(certInfo.integrityHMAC, "integrityHMAC");
            m.Put(certInfo.encIdentity.Length, "encIdentity");
            m.Put(certInfo.encIdentity, "encIdentity.Length");
            byte[] certInfoBytes = m.GetBytes();

            // Here the CA passes certInfoBytes and encSecret (as well as the encrypted
            // AIK certificate) back to the device via network.


            //////////////////////////////////////////////////////////////////////////////
            // Device side code again
            //////////////////////////////////////////////////////////////////////////////

            // Unmarshal certInfo and encSecret (and encrypted AIK certificate)

            m = new Marshaller(certInfoBytes);
            int len = m.Get <int>();

            certInfo.integrityHMAC = m.GetArray <byte>(len);
            len = m.Get <int>();
            certInfo.encIdentity = m.GetArray <byte>(len);
            // encSecret is a byte array, so, normally, no special unmarshalling is required

            // Create policy session to authorize AIK usage
            AuthSession sessAIK = tpm.StartAuthSessionEx(TpmSe.Policy, nameAlg);

            sessAIK.RunPolicy(tpm, policyAIK, "Activate");

            // Create policy description and corresponding policy session to authorize EK usage
            var policyEK = new PolicyTree(EKpub.nameAlg);

            policyEK.SetPolicyRoot(new TpmPolicySecret(TpmRh.Endorsement, false, 0, null, null));

            AuthSession sessEK = tpm.StartAuthSessionEx(TpmSe.Policy, EKpub.nameAlg);

            sessEK.RunPolicy(tpm, policyEK);

            byte[] recoveredSecretKey = tpm[sessAIK, sessEK].ActivateCredential(hAIK, hEK, certInfo, encSecret);

            testCtx.AssertEqual("Secret.1", recoveredSecretKey, secretKey);

            // Here the device can use recoveredSecretKey to decrypt the AIK certificate

            //////////////////////////////////////////////////////////////////////////////
            // End of activation sequence
            //////////////////////////////////////////////////////////////////////////////


            //
            // Now prepare activation using the TPM built-in command
            //

            byte[]   encSecret2 = null;
            IdObject certInfo2  = tpm.MakeCredential(hEK, secretKey, AIKpub.GetName(), out encSecret2);

            // Reinitialize policy sessions
            tpm.PolicyRestart(sessAIK);
            sessAIK.RunPolicy(tpm, policyAIK, "Activate");
            tpm.PolicyRestart(sessEK);
            sessEK.RunPolicy(tpm, policyEK);

            recoveredSecretKey = tpm[sessAIK, sessEK].ActivateCredential(hAIK, hEK, certInfo2, encSecret2);
            testCtx.AssertEqual("Secret.2", recoveredSecretKey, secretKey);

            // Cleanup
            tpm.FlushContext(sessAIK);
            tpm.FlushContext(sessEK);
            tpm.FlushContext(hAIK);

            if (hEK.handle != 0x81010001)
            {
                tpm.FlushContext(hEK);
            }
        } // ActivateAikSample
Esempio n. 29
0
        /// <summary>
        /// Activates an identity key within the TPM device.
        /// </summary>
        /// <param name="encryptedKey">The encrypted identity key.</param>
        public override void ActivateIdentityKey(byte[] encryptedKey)
        {
            if (Logging.IsEnabled)
            {
                Logging.Enter(this, $"{encryptedKey}", nameof(ActivateIdentityKey));
            }
            Destroy();

            // Take the pieces out of the container
            var           m      = new Marshaller(encryptedKey, DataRepresentation.Tpm);
            Tpm2bIdObject cred2b = m.Get <Tpm2bIdObject>();

            byte[] encryptedSecret = new byte[m.Get <ushort>()];
            encryptedSecret = m.GetArray <byte>(encryptedSecret.Length, "encryptedSecret");
            TpmPrivate dupBlob = m.Get <TpmPrivate>();

            byte[] encWrapKey = new byte[m.Get <ushort>()];
            encWrapKey = m.GetArray <byte>(encWrapKey.Length, "encWrapKey");
            UInt16 pubSize = m.Get <UInt16>();

            _idKeyPub = m.Get <TpmPublic>();
            byte[] cipherText = new byte[m.Get <ushort>()];
            cipherText = m.GetArray <byte>(cipherText.Length, "uriInfo");

            // Setup the authorization session for the EK
            var policyNode = new TpmPolicySecret(TpmHandle.RhEndorsement, false, 0, Array.Empty <byte>(), Array.Empty <byte>());
            var policy     = new PolicyTree(_ekPub.nameAlg);

            policy.SetPolicyRoot(policyNode);
            AuthSession ekSession = _tpm2.StartAuthSessionEx(TpmSe.Policy, _ekPub.nameAlg);

            ekSession.RunPolicy(_tpm2, policy);

            // Perform the activation
            ekSession.Attrs  &= ~SessionAttr.ContinueSession;
            _activationSecret = _tpm2[Array.Empty <byte>(), ekSession].ActivateCredential(
                new TpmHandle(TPM_20_SRK_HANDLE),
                new TpmHandle(TPM_20_EK_HANDLE),
                cred2b.credential,
                encryptedSecret);

            TpmPrivate importedKeyBlob = _tpm2.Import(
                new TpmHandle(TPM_20_SRK_HANDLE),
                _activationSecret,
                _idKeyPub,
                dupBlob,
                encWrapKey,
                new SymDefObject(TpmAlgId.Aes, 128, TpmAlgId.Cfb));

            _idKeyHandle = _tpm2.Load(new TpmHandle(TPM_20_SRK_HANDLE), importedKeyBlob, _idKeyPub);

            // Persist the key in NV
            TpmHandle hmacKeyHandle = new TpmHandle(AIOTH_PERSISTED_KEY_HANDLE);

            _tpm2.EvictControl(new TpmHandle(TpmRh.Owner), _idKeyHandle, hmacKeyHandle);

            // Unload the transient copy from the TPM
            _tpm2.FlushContext(_idKeyHandle);
            _idKeyHandle = hmacKeyHandle;

            if (Logging.IsEnabled)
            {
                Logging.Exit(this, $"{encryptedKey}", nameof(ActivateIdentityKey));
            }
        }
Esempio n. 30
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();
        }