Thanks for sharing your code and error details! Here's a step-by-step guide to help you fix the issue with importing an externally-generated AES key into TPM using TSS.NET:
Step-by-Step Fix
Understand the Error The TPM is rejecting your Import()
call because the object attributes in TpmPublic
are not valid for importing a symmetric key. The error says {Attributes}
is the problem.
- Update Object Attributes You're currently using
ObjectAttr.Decrypt | ObjectAttr.Encrypt | ObjectAttr.FixedTPM | ObjectAttr.FixedParent | ObjectAttr.UserWithAuth Instead, use: csharp
This removes attributes that are only valid for TPM-generated keys (ObjectAttr.Decrypt | ObjectAttr.Encrypt | ObjectAttr.UserWithAuth
FixedTPM
,FixedParent
,SensitiveDataOrigin
).
3.Check Name Algorithm If you're not using a policy, you can set the name algorithm toTpmAlgId.Null
: csharp
Otherwise,TpmAlgId.Null
TpmAlgId.Sha256
is fine. 4.Update YourTpmPublic
Definition Here's the corrected version:
csharpTpmPublic importKeyTemplate = new TpmPublic( TpmAlgId.Sha256, // or TpmAlgId.Null ObjectAttr.Decrypt | ObjectAttr.Encrypt | ObjectAttr.UserWithAuth, null, new SymDefObject(symDef), new Tpm2bDigestSymcipher()
Let us know if the issue persists after following these steps. We’ll be happy to assist further if needed. If the issue has been resolved, kindly mark the response as answered."**5.Try Again** With the updated attributes, rerun your code. The `Import()` call should now succeed. Here's your updated `StoreSymmetricKeyToTpm` method with the necessary changes applied to fix the import issue: **Updated Method:** `StoreSymmetricKeyToTpm` `public TpmHandle StoreSymmetricKeyToTpm(byte[] keyBytes)` `{` ` // Define the symmetric key parameters` ` SymDefObject symDef = new SymDefObject(TpmAlgId.Aes, defaultSymKeyBits, defaultSymKeyMode);` ` // Create a SymCipher object from the raw key bytes` ` SymCipher symKey = SymCipher.Create(symDef, keyBytes);` ` // Updated object attributes for importing a symmetric key` ` ObjectAttr attrs = ObjectAttr.Decrypt | ObjectAttr.Encrypt | ObjectAttr.UserWithAuth;` ` // Use a valid name algorithm (Sha256 or Null if no policy is used)` ` TpmAlgId nameAlg = TpmAlgId.Sha256;` ` // Create a public area for the AES key` ` TpmPublic importKeyTemplate = new TpmPublic(` ` nameAlg,` ` attrs,` ` null,` ` new SymDefObject(symDef),` ` new Tpm2bDigestSymcipher()` ` );` ` // Wrap the externally created AES key for import` ` TssObject aesKeyWrapper = TssObject.Create(importKeyTemplate, new AuthValue(defaultUserAuthChain));` ` // Get the public part of the parent key` ` TpmPublic tempParentPubKey = _tpm2.ReadPublic(_primaryHandle, out _, out _);` ` // Create duplication blob and encrypted seed` ` byte[] encSecret;` ` TpmPrivate duplicationBlob = aesKeyWrapper.GetDuplicationBlob(tempParentPubKey, symKey, out encSecret);` ` // Import the wrapped key into the TPM` ` TpmPrivate importedPvt = _tpm2.Import(_primaryHandle, symKey, aesKeyWrapper.Public, duplicationBlob, encSecret, new SymDefObject(symDef));` ` // Load the imported key into the TPM` ` TpmHandle loadedKeyHandle = _tpm2.Load(_primaryHandle, importedPvt, aesKeyWrapper.Public)` ` .SetAuth(new AuthValue(defaultUserAuthChain));` ` // Make the key persistent` ` TpmHandle persistentHandle = new TpmHandle((uint)TpmHc.PersistentFirst + 0x20); // Use a unique persistent handle` ` _tpm2._ExpectResponses(TpmRc.Success, TpmRc.NvSpace, TpmRc.NvDefined)` ` .EvictControl(TpmRh.Owner, loadedKeyHandle, persistentHandle);` ` // Optionally flush the transient handle` ` _tpm2.FlushContext(loadedKeyHandle);` ` // Save and return the persistent handle` ` _aesKeyHandle = persistentHandle;` ` return persistentHandle;` `}`