Example #1
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);
        }
Example #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);
        }
Example #3
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);
        }
Example #4
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);
        }
Example #5
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);
        }
Example #6
0
        public async Task <Tpm2CreateResponse> CreateAsync(
            TpmHandle parentHandle,
            SensitiveCreate inSensitive,
            TpmPublic inPublic,
            byte[] outsideInfo,
            PcrSelection[] creationPCR)
        {
            var inS  = new Tpm2CreateRequest(parentHandle, inSensitive, inPublic, outsideInfo, creationPCR);
            var resp = new Tpm2CreateResponse();
            await Task.Run(() => DispatchMethod(TpmCc.Create, inS, resp, 1, 0));

            return(resp);
        }
Example #7
0
        public async Task <Tpm2CreateResponse> CreateAsync(
            TpmHandle parentHandle,
            SensitiveCreate inSensitive,
            TpmPublic inPublic,
            byte[] outsideInfo,
            PcrSelection[] creationPCR)
        {
            var inS = new Tpm2CreateRequest(parentHandle, inSensitive, inPublic, outsideInfo, creationPCR);
            TpmStructureBase outSBase = null;
            await Task.Run(() => DispatchMethod(TpmCc.Create, inS, typeof(Tpm2CreateResponse), out outSBase, 1, 0));

            var outS = (Tpm2CreateResponse)outSBase;

            return(outS);
        }
Example #8
0
        /// <summary>
        /// Create a non-migratable RSA primary with the specified use-auth value and key size.
        /// </summary>
        /// <param name="parentAuth"></param>
        /// <param name="keyLen"></param>
        /// <param name="restricted"></param>
        /// <param name="useAuth"></param>
        /// <param name="parentHandle"></param>
        /// <param name="policy"></param>
        /// <returns></returns>
        public async Task <Tpm2CreateResponse> CreateRsaSigningAsync(
            TpmHandle parentHandle,
            AuthValue parentAuth,
            int keyLen,
            bool restricted,
            AuthValue useAuth,
            TpmHash policy = null)
        {
            ObjectAttr attr = ObjectAttr.Sign | ObjectAttr.FixedParent | ObjectAttr.FixedTPM | // Non-duplicatable
                              ObjectAttr.SensitiveDataOrigin | ObjectAttr.UserWithAuth;        // Authorize with auth-data

            if (restricted)
            {
                attr |= ObjectAttr.Restricted;
            }

            var thePolicy = new byte[0];

            if ((Object)policy != null)
            {
                thePolicy = policy;
                attr     |= ObjectAttr.AdminWithPolicy;
            }

            var signKeyPubTemplate = new TpmPublic(H.NameHash,
                                                   attr,
                                                   thePolicy,
                                                   new RsaParms(new SymDefObject(),
                                                                // Key type and sig scheme
                                                                H.RsaSigScheme,
                                                                (ushort)keyLen,
                                                                0),
                                                   new Tpm2bPublicKeyRsa());

            // Auth-data for new key
            var sensCreate = new SensitiveCreate(useAuth, new byte[0]);

            // Create the key
            var newKey = await H.Tpm[parentAuth].CreateAsync(parentHandle,
                                                             sensCreate,
                                                             signKeyPubTemplate,
                                                             new byte[0],
                                                             new PcrSelection[0]);

            return(newKey);
        }
Example #9
0
        internal async Task <Tpm2CreatePrimaryResponse> CreatePrimaryRsaAsyncInternal(
            int keyLen,
            byte[] useAuth,
            byte[] policyAuth,
            PcrSelection[] pcrSel)
        {
            ObjectAttr attr = ObjectAttr.Restricted | ObjectAttr.Decrypt
                              | ObjectAttr.FixedParent | ObjectAttr.FixedTPM
                              | ObjectAttr.SensitiveDataOrigin;

            var theUseAuth = new byte[0];

            if (useAuth != null)
            {
                theUseAuth = useAuth;
                attr      |= ObjectAttr.UserWithAuth;
            }
            var thePolicyAuth = new byte[0];

            if (policyAuth != null)
            {
                thePolicyAuth = policyAuth;
                attr         |= ObjectAttr.AdminWithPolicy;
            }
            var theSelection = new PcrSelection[0];

            if (pcrSel != null)
            {
                theSelection = pcrSel;
            }

            var sensCreate = new SensitiveCreate(theUseAuth, new byte[0]);
            var parms      = new TpmPublic(H.NameHash,
                                           attr,
                                           thePolicyAuth,
                                           new RsaParms(new SymDefObject(TpmAlgId.Aes, 128, TpmAlgId.Cfb),
                                                        new NullAsymScheme(),
                                                        (ushort)keyLen,
                                                        0),
                                           new Tpm2bPublicKeyRsa());

            byte[] outsideInfo = Globs.GetRandomBytes(8);
            return(await H.Tpm.CreatePrimaryAsync(TpmRh.Owner, sensCreate,
                                                  parms, outsideInfo, theSelection));
        }
Example #10
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);
        }
Example #11
0
        public async Task <Tpm2CreatePrimaryResponse> CreatePrimaryAsync(
            TpmHandle primaryHandle,
            SensitiveCreate inSensitive,
            TpmPublic inPublic,
            byte[] outsideInfo,
            PcrSelection[] creationPCR)
        {
            var inS = new Tpm2CreatePrimaryRequest {
                primaryHandle = primaryHandle,
                inSensitive   = inSensitive,
                inPublic      = inPublic,
                outsideInfo   = outsideInfo,
                creationPCR   = creationPCR
            };
            TpmStructureBase outSBase = null;
            await Task.Run(() =>
                           DispatchMethod(TpmCc.CreatePrimary, inS, typeof(Tpm2CreatePrimaryResponse), out outSBase, 1, 1));

            var outS = (Tpm2CreatePrimaryResponse)outSBase;

            return(outS);
        }
Example #12
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);
        }
Example #13
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);
        }
Example #14
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
Example #15
0
        } // CreateRsaPrimaryStorageKey()

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

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

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

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

            byte[] creationHash;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            Console.WriteLine("Signature verified.");

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

            Console.WriteLine("PCR Quote sample finished.");
        } // QuotePcrs()
Example #16
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);
        }
Example #17
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);
        }