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