tpm2-tss
tpm2-tss copied to clipboard
How to load a key which was generated in tpm by using openssl?
I generate a key by performing Esys_CreatePrimary and get the public portion of the key.Then I use openssl to load the public key,but it throw exception which say 'Failed to load public key'.Is it possible to use openssl to load a key?
Generate the key and get the public key:
Esys_CreatePrimary(esysContext, ESYS_TR_RH_ENDORSEMENT, session, ESYS_TR_NONE, ESYS_TR_NONE, &inSensitive, &inPublic, &outsideInfo, &creationPCR, &objectHandle, outPublic, creationData, creationHash, creationTicket);
Load the key:
char* p = new char[outPublic->publicArea.unique.rsa.size]; memcpy(p, outPublic->publicArea.unique.rsa.buffer, outPublic->publicArea.unique.rsa.size); std::string publicKey(p); std::istringstream keyStream(publicKey); RSAKey rsaKey(&keyStream, 0, "");
It throw exception after performing RSAKey rsaKey(&keyStream, 0, "");
.
What's wrong it?
'RSAKey' is defined in 'Poco/Crypto/RSAKey.h'.
The version of openssl is 1.1.1q.The version of Poco is 1.11.1.
If you want to see how to convert a tpm2 public key to an openssl public key in C you could check the following programs from the tpm tools:
https://github.com/tpm2-software/tpm2-tools/blob/8cbc4bbaebc4fa135e35dabd6d9ab36ac05eb72b/lib/tpm2_convert.c#L95 to create an EVP object. or
https://github.com/tpm2-software/tpm2-tools/blob/8cbc4bbaebc4fa135e35dabd6d9ab36ac05eb72b/lib/tpm2_convert.c#L418
to create pem or der format.
These programs are used by tpm2_readpublic
. E.g.:
tpm2_readpublic -c 0x81000001 -f pem -o pubkey.pem
If you create the key with FAPI you can get the pem data of the public key with the function Fapi_ExportKey (field pem_ext_public
in the json output)
If you want to use TPM keys with openssl 1.1.1 you could also check:
https://github.com/tpm2-software/tpm2-tss-engine
Thanks for your information.I work on Esys api.Now I succeed to convert rsa public key to pem and read the pem data of public key by using openssl.However,when I call the RSA_public_decrypt to decrypt the signature while is generated by calling Esys_Sign,it return -1 that means error.How do I do?
`void VerifySignatureByOpenssl(TPMT_SIGNATURE* signature) {
ifstream s;
string buf;
string temp;
s.open(".\\pkey.pem");
while (getline(s, temp)) {
buf += temp + "\n";
}
s.close();
cout << buf << endl;
BIO* bio = BIO_new_mem_buf((unsigned char *)buf.c_str(), -1);
RSA* rsa = RSA_new();
rsa = PEM_read_bio_RSA_PUBKEY(bio, &rsa, NULL, NULL);
if (rsa == NULL) {
cout << "rsa is NULL" << endl;
return;
}
int len = RSA_size(rsa);
char* text = new char[len + 1];
memset(text, 0, len + 1);
// std::string clearText = "abcdefghijklmnopqrstuvwxyz";
// int ret = RSA_public_encrypt(clearText.size(), (const unsigned char*)clearText.c_str(), (unsigned char*)text, rsa, RSA_PKCS1_PADDING); // It's ok to encrypt.
int ret = RSA_public_decrypt(signature->signature.rsassa.sig.size, signature->signature.rsassa.sig.buffer, (unsigned char*)text, rsa, RSA_PKCS1_PADDING);
if (ret < 0) {
cout << "RSA_public_decrypt failed,ret is " << ret << endl;
return;
}
string str = string(text, ret);
cout << str << endl;
}`
From man page RSA_public_decrypt:
RSA_PKCS1_PADDING PKCS 1 v1.5 padding. This function does not handle the algorithmIdentifier specified in PKCS 1. When generating or verifying PKCS 1 signatures, RSA_sign(3) and RSA_verify(3) should be used.
Does it mean that it's impossible to use RSA_verify to verify the signature generated by TPM such as Esys_Sign,Esys_Quote or Esys_Certify?If I use RSA_sign to get the signature,how do I do to convert the private key to RSA object?The private key generated by Esys_Create is encrypted,right?
What kind of padding scheme is used in Esys_Sign?I use RSA_ verify to verify the signature generated by Esys_Sign and I get the error:0407008A:rsa routines:RSA_padding_check_PKCS1_type_1:invalid padding.I don't find the description about the padding scheme Esys_Sign uses in the part 3 of TCG standard file.
You chan see howto verify a signature with an evp public key in C at: https://github.com/tpm2-software/tpm2-tss/blob/6bff243f98d554040facfef54508472d7ff46e9a/src/tss2-fapi/fapi_crypto.c#L862
It works when the padding scheme is RSA_PKCS1_PSS_PADDING.Thanks for your help!
I create a primary key and its nameAlg is TPM2_ALG_SHA256.I use the Esys_ReadPublic to get the name.Now I wonder why the size of the name is 34.It should be 32 if my understanding is correct.
The first two bytes of the name are the nameAlg (0x000b) in your case.
Thanks for your suggestion.I want to store a external certificate in TPM.Are there any requirements for the format of the certificate?Should I use ESYS_CreatePrimary to create the sealed data of certificate?
Normally the certificate contains public information to verify the identity of the entity associated with the certificate. So sealing should not be necessary. If you want to store it in the TPM you could write it to the NV ram.
I make a program and succeed to use Esys_EvictControl to get a persistent handle.Then I copy the program to the other computer and try to use Esys_EvictControl.It return error:Received a non-TPM Error.But actually there is.It make none sense.
By the way,the former is desktop,the latter is laptop.I try several laptops and all failed.
I try the program on another desktop and still fail.Is it related to the manufacturer of TPM?
It's difficult to say what's the problem without more information. Did all other commands before Esys_EvictControl was called work without problems and was was the error code?
It's okey to create EK.
And what's the error code after creating the EK and calling Esys_EvictControl?
Creating the EK didn't return error.Esys_EvictControl return the error code:0x80280400.
Could you please create a trace to see what exactly happens: TSS2_LOG=all+trace your_programm
I‘ve figure it out.I should run the program with administrator privileges.
I generate the AK and persist it into the TPM. I use the TPMI_DH_PERSISTENT handle to specify its location in the TPM, and when I want to use this AK I need to use Esys_TR_FromTPMPublic to generate the ESYS_TR handle through the TPMI_DH_PERSISTENT handle. Now what I want to know is, if I lose the TPMI_DH_PERSISTENT handle, is there a way to find the AK again?
The tool command tpm2_getcap handles-persistent
will list the persistent handles.
tpm2_getcap
uses the esys function Esys_GetCapability
to find the persistent handles.
Thanks for your help.
I build the tpm2-tss.sln to generate static libraries and import them in a VC project.It returns errors when I build the project: 1>tss2-tcti-tbs.lib(tcti-tbs.obj) : error LNK2001: unresolved external symbol _Tbsip_Submit_Command@28 1>tss2-tcti-tbs.lib(tcti-tbs.obj) : error LNK2001: unresolved external symbol _Tbsip_Context_Close@4 1>tss2-tcti-tbs.lib(tcti-tbs.obj) : error LNK2001: unresolved external symbol _Tbsip_Cancel_Commands@4 1>tss2-tcti-tbs.lib(tcti-tbs.obj) : error LNK2001: unresolved external symbol _Tbsi_Context_Create@8 1>tss2-tcti-tbs.lib(tcti-tbs.obj) : error LNK2001: unresolved external symbol _Tbsi_GetDeviceInfo@8
static libraries: tss2-esys.lib tss2-sys.lib tss2-mu.lib tss2-rc.lib tss2-tctildr.lib tss2-tcti-mssim.lib tss2-tcti-tbs.lib
It's normal to generate dynamic libraries.How to use static libraries? I really need some help.
@SAO-kirito-asuna sorry I can't help with VC projects because I do not use Windows.
Hi.I use Esys_EvictControl to get a persistent handle.However,it seems that anyone can also delete this handle without any authorization.Like I create a key with the digest of policy session and the TPMA_OBJECT_USERWITHAUTH is CLEAR.I need to ensure there is a policy authorization provided when someone want to delete the persistent handle.Is it viable?
For Esys_EvictControl only the used hierarchy needs to be authorized. You can use Esys_SetPrimaryPolicy or Esys_HierarchyChangeAuth to set the authorization.
Hi.Does the TPM support 3072 RSA?If it does,how to set the public parameters? Thanks.
There are TPMs which support 3072 bits. You have to set the size in publicArea.parameters.keyBits. FAPI currently does not support serialization of 3072bit public info and currently has no default profile for RSA3072. I will create a PR that at least serialization is possible.