} // 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
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); }
} // QuotePcrs() /// <summary> /// This sample demonstrates the creation and use of a storage root key that /// behaves like the Storage Root Key (SRK) defined in TPM1.2. /// To do this we need to create a new primary, and then use EvictControl /// to make it NV-resident. /// </summary> /// <param name="tpm">Reference to TPM object</param> static void StorageRootKey(Tpm2 tpm) { Console.WriteLine("\nStorageRootKey sample started."); // // This template asks the TPM to create an 2048 bit RSA storage key // with an associated AES key for symmetric protection of its child keys. // NOTE - The term SRK is not used in TPM 2.0 spec, but is widely used // in other documents. // var srkTemplate = new TpmPublic(TpmAlgId.Sha256, // Name algorithm ObjectAttr.Restricted | // Storage keys must be restricted ObjectAttr.Decrypt | // Storage keys are Decrypt keys ObjectAttr.FixedParent | ObjectAttr.FixedTPM | // Non-duplicable (like 1.2) ObjectAttr.UserWithAuth | ObjectAttr.SensitiveDataOrigin, null, // No policy new RsaParms(new SymDefObject(TpmAlgId.Aes, 128, TpmAlgId.Cfb), new NullAsymScheme(), // No signing or decryption scheme 2048, 0), // 2048-bit RSA new Tpm2bPublicKeyRsa()); AuthValue childAuthVal = AuthValue.FromRandom(8); TssObject swKey = TssObject.Create(srkTemplate, childAuthVal); TpmPublic srkPublic; CreationData srkCreationData; TkCreation srkCreationTicket; byte[] srkCreationHash; // // Ask the TPM to create a new primary RSA/AES primary storage key // TpmHandle keyHandle = tpm.CreatePrimary(TpmRh.Owner, // In the owner-hierarchy new SensitiveCreate(null, null), // Empty auth-value srkTemplate, // Key template (params) null, // For creation ticket new PcrSelection[0], // For creation ticket out srkPublic, // Out pubKey and attrs out srkCreationData, // Not used here out srkCreationHash, // Ibid out srkCreationTicket); // Ibid // // print out text-versions of the public key just created // Console.WriteLine("New SRK public key\n" + srkPublic.ToString()); // // The caller provides the handle for persistent keys // TpmHandle srkHandle = TpmHandle.Persistent(0x5000); // // Ae will make the "SRK" persistent in an NV-slot, so clean up anything // that is already there // tpm._AllowErrors() .EvictControl(TpmRh.Owner, srkHandle, srkHandle); if (tpm._LastCommandSucceeded()) { Console.WriteLine("Removed previous persistent SRK."); } // // Make the SRK NV-resident // tpm.EvictControl(TpmRh.Owner, keyHandle, srkHandle); Console.WriteLine("SRK is persistent now."); Console.WriteLine("\nStorageRootKey sample finished."); } // StorageRootKey()
/// <summary> /// Performs the following operations: /// - Generates in software (using TSS.net helpers) a key with the given template, /// - Creates TPM-compatible dupliction blob for the given TPM based parent key, /// - Import the duplication blob into TPM /// - Loads the imported key into the TPM /// - Makes sure that the imported key works. /// </summary> /// <param name="tpm">TPM instance to use</param> /// <param name="keyPub">Template for the software generated key.</param> /// <param name="hParent">Intended TPM based parent key for the software generated key.</param> /// <param name="innerSymDef">Specification of the optional inner wrapper for the duplication blob.</param> static void GenerateAndImport(Tpm2 tpm, TpmPublic keyPub, TpmHandle hParent, SymDefObject innerSymDef = null) { // // Create a software key with the given template // // Generate a random auth value for the key to be created (though we could // use an empty buffer, too). var keyAuth = AuthValue.FromRandom(CryptoLib.DigestSize(keyPub.nameAlg)); // Generate the key TssObject swKey = TssObject.Create(keyPub, keyAuth); // // Create duplication blob for the new key with the SRK as the new parent // // Create a symmetric software key if an inner wrapper is requested. var innerWrapKey = innerSymDef == null ? null : SymCipher.Create(innerSymDef); // Retrieve the public area of the intended parent key from the TPM // We do not need the name (and qualified name) of the key here, but // the TPM command returns them anyway. // NOTE - Alternatively we could get the public area from the overloaded // form of the CreateRsaPrimaryStorageKey() helper used to create the parent // key, as all TPM key creation commands (TPM2_CreatePrimary(), TPM2_Create() // and TPM2_CreateLoaded()) return it. byte[] name, qname; TpmPublic pubParent = tpm.ReadPublic(hParent, out name, out qname); byte[] encSecret; TpmPrivate dupBlob = swKey.GetDuplicationBlob(pubParent, innerWrapKey, out encSecret); // Import the duplication blob into the TPM TpmPrivate privImp = tpm.Import(hParent, innerWrapKey, swKey.Public, dupBlob, encSecret, innerSymDef ?? new SymDefObject()); // Load the imported key ... TpmHandle hKey = tpm.Load(hParent, privImp, swKey.Public) .SetAuth(swKey.Sensitive.authValue); // ... and validate that it works byte[] message = Globs.GetRandomBytes(32); if (keyPub.objectAttributes.HasFlag(ObjectAttr.Decrypt)) { // Encrypt something if (keyPub.type == TpmAlgId.Symcipher) { // Only need software symcypher here to query IV size. // Normally, when you use a fixed algorithm, you can hardcode it. var swSym = SymCipher.Create(keyPub.parameters as SymDefObject); byte[] ivIn = Globs.GetRandomBytes(swSym.IVSize), ivOut = null; byte[] cipher = swKey.Encrypt(message, ref ivIn, out ivOut); // Not all TPMs implement TPM2_EncryptDecrypt() command tpm._ExpectResponses(TpmRc.Success, TpmRc.TbsCommandBlocked); byte[] decrypted = tpm.EncryptDecrypt(hKey, 1, TpmAlgId.Null, ivIn, cipher, out ivOut); if (tpm._LastCommandSucceeded()) { bool decOk = Globs.ArraysAreEqual(message, decrypted); Console.WriteLine("Imported symmetric key validation {0}", decOk ? "SUCCEEDED" : "FAILED"); } } } else { // Sign something (works for both asymmetric and MAC keys) string keyType = keyPub.type == TpmAlgId.Rsa ? "RSA" : keyPub.type == TpmAlgId.Keyedhash ? "HMAC" : "UNKNOWN"; // Should not happen in this sample TpmAlgId sigHashAlg = GetSchemeHash(keyPub); TpmHash toSign = TpmHash.FromData(sigHashAlg, message); var proofx = new TkHashcheck(TpmRh.Null, null); ISignatureUnion sig = tpm.Sign(hKey, toSign, null, proofx); bool sigOk = swKey.VerifySignatureOverHash(toSign, sig); Console.WriteLine("Imported {0} key validation {1}", keyType, sigOk ? "SUCCEEDED" : "FAILED"); } // Free TPM resources taken by the loaded imported key tpm.FlushContext(hKey); } // GenerateAndImport