void ExternalKeyImportSample(Tpm2 tpm, TestContext testCtx) { // Create a software key (external to any TPM). int keySize = 2048; var externalRsaKey = new RawRsa(keySize); // When an external key comes from a cert, one would need to extract the key size and // byte buffers representing public and private parts of the key from the cert, an use // them directly in the call to ImportExternalRsaKey() below (i.e. no RawRsa object is // necessary). // Signing scheme to use (it may come from the key's cert) TpmAlgId sigHashAlg = Substrate.Random(TpmCfg.HashAlgs); var sigScheme = new SchemeRsassa(sigHashAlg); // An arbitrary external key would not have TPM key attributes associated with it. // Yet some of them may be inferred from the cert based on the declared key purpose // (ObjectAttr.Sign below). The others are defined by the intended TPM key usage // scenarios, e.g. ObjectAttr.UserWithAuth tells TPM to allow key usage authorization // using an auth value (random byte buffer) in a password or an HMAC session. ObjectAttr keyAttrs = ObjectAttr.Sign | ObjectAttr.UserWithAuth; // Generate an auth value for the imported matching in strength the signing scheme byte[] authVal = Substrate.RandomAuth(sigHashAlg); // We need a storage key to use as a parent of the imported key. // The following helper creates an RSA primary storage key. TpmHandle hParent = Substrate.CreateRsaPrimary(tpm); TssObject importedKey = ImportExternalRsaKey(tpm, hParent, keySize, sigScheme, externalRsaKey.Public, externalRsaKey.Private, keyAttrs, authVal); // Now we can load the newly imported key into the TPM, ... TpmHandle hImportedKey = tpm.Load(hParent, importedKey.Private, importedKey.Public); // ... let the TSS know the auth value associated with this handle, ... hImportedKey.SetAuth(authVal); // ... and use it to sign something to check if import was OK TpmHash toSign = TpmHash.FromRandom(sigHashAlg); ISignatureUnion sig = tpm.Sign(hImportedKey, toSign, null, new TkHashcheck()); // Verify that the signature is correct using the public part of the imported key bool sigOk = importedKey.Public.VerifySignatureOverHash(toSign, sig); testCtx.Assert("Signature.OK", sigOk); // Cleanup tpm.FlushContext(hImportedKey); // The parent key handle can be flushed immediately after it was used in the Load() command tpm.FlushContext(hParent); // Imported private/public key pair (in the TssObject) can be stored on disk, in the cloud, // etc. (no additional protection is necessary), and loaded into the TPM as above whenever // the key is needed. // Alternatively the key can be persisted in the TPM using the EvictControl() command } // ExternalKeyImportSample