> -----Original Message-----
> From: Ashok Kumar [mailto:email@example.com]
> Sent: Thursday, March 26, 2020 6:49 AM
> To: firstname.lastname@example.org
> Subject: [tpm2] TPM Encryption Key
> Our requirement is to encrypt the given data (for example, private key) with TPM
> As and when required, decrypt the data using the TPM key and use it in the
> To address this requirement, did the following.
> First time initialization:
> - Generated primary key under owner hierarchy
> - Created the TPM symmetric key (which is used to encrypt/decrypt application
> under the primary key.
> - Used Esys_EvictControl() to store the TPM key handle in the TPM persistent
> During Encryption/Decryption:
> - Used Esys_TR_FromTPMPublic() to fetch existing TPM key handle from the
> persistent memory
I don't understand, tpm2_evictcontrol will give you a persistent key handle that’s good.
Why did you do this step, to get an ESYS_TR handle?
Yes. If this API succeeds, I skipped the above mentioned initialization steps (including primary key create)
during the process initialization. That was done just to save some time during the initialization.
Agree that we don't need this step functionality wise as we can recreate the same primary key handle.
If we make any change in the public params (though that is not expected) in future release,
thought this approach would help to get the key handle used for encrypting the private key.
I also urge folks to use transient memory. tpm2_create will provide a public and
private blob that can be loaded with tpm2_load and then used. Persistent memory
is only so big. So use wisely.
Sure, that sounds good.
> - Used Esys_EncryptDecrypt() to encrypt/decrypt the given data
> Is this the right approach?
> It worked fine with simulator. However, it failed with "command code not
> supported" error with TPM device.
Not many TPMs support symmetric encryption:
Let's look into your TPMs supported command set, do:
$ tpm2_getcap commands | grep -i encrypt
If you don't have them, it won't work.
tpm2_getcap command is not available in my system. Instead, have tpm2_dump_capability command.
Confirmed that TPM2_CC_EncryptDecrypt and TPM2_CC_EncryptDecrypt2 commands are not supported.
RSA_Decrypt and RSA_Encrypt are supported
[admin@TPM2-VersaCSG-Ashok: ~] $ tpm2_dump_capability -p 2323 -c commands | grep -A 8 159
[admin@TPM2-VersaCSG-Ashok: ~] $ tpm2_dump_capability -p 2323 -c commands | grep -A 8 174
What you could do, is:
1. If you have to store externally generated private keys, use tpm2_import.
2. seal an AES key to the tpm with tpm2_create -I and wrap the key with that key.
1 is the better option. Because once you do that, you can scrub all unprotected occurrences of
the key in plaintext, and let it be a managed TPM object, protected by the TPM.
Thanks for your suggestion. After the tpm2_import, how do we get the plain text (key) back?
What is the command to get the original text?
> esys/api/Esys_EncryptDecrypt.c:324:Esys_EncryptDecrypt_Finish() Received TPM
> Esys Finish ErrorCode (0x00000143)
> versa_tpm2_encrypt_decrypt.382: Esys_EncryptDecrypt failed; rc 0x143
> main#568: Wrote 0 bytes of data
> [admin@TPM2-VersaCSG-Ashok: ~] $ tpm2_rc_decode 0x143 error layer
> hex: 0x0
> identifier: TSS2_TPM_ERROR_LEVEL
> description: Error produced by the TPM format 0 error code
> hex: 0x43
> name: TPM_RC_COMMAND_CODE
> description: command code not supported
> From the tpm2_dump_capability, looks like Esys_EncryptDecrypt() and
> Esys_EncryptDecrypt2() are not supported.
> For our usecase, what could be the right alternative method to use? Shall we use
> Esys_RSA_Encrypt()? In that case, which scheme is better? TPM2_ALG_RSAES or
> Ashok Kumar