Closed sumanth797 closed 10 months ago
1) The private key never leaves the TPM chip, so you never get the BEGIN PRIVATE KEY
. It will always be the BEGIN TSS2 PRIVATE KEY
, however:
2) Using the tpm2
provider the BEGIN TSS2 PRIVATE KEY
can be loaded into the EVP_PKEY
structure and used in all situations (with some restrictions) like any other private key. Have a look at https://github.com/tpm2-software/tpm2-openssl/blob/master/test/rsa_genpkey_decrypt.c
Hi , I have used the above example for loading into EVP_PKEY structure. https://github.com/tpm2-software/tpm2-openssl/blob/master/test/rsa_genpkey_decrypt.c
I'm loading the provider from this path if ((defprov = OSSL_PROVIDER_load(NULL, "/usr/lib64/ossl-packages/tpm2.so")) == NULL) goto error;
It is throwing this error, PROVIDER INIT RSA GEN INIT rsa 3 RSA GEN_SET_PARAMS [ bits ] RSA GEN 2048 bits RSA GEN parent: primary 0x40000001 WARNING:esys:src/tss2-esys/api/Esys_CreatePrimary.c:400:Esys_CreatePrimary_Finish() Received TPM Error ERROR:esys:src/tss2-esys/api/Esys_CreatePrimary.c:135:Esys_CreatePrimary() Esys Finish ErrorCode (0x000009a2) RSA FREE RSA CLEANUP 80CB564DE77F0000:error:40000002:/usr/lib64/ossl-packages/tpm2.so:tpm2_build_primary:authorization failure:src/tpm2-provider-pkey.c:316: PROVIDER TEARDOWN Can you help me how to pass the password and rectify this issue?
You need to set the parent-auth
parameter as described in https://github.com/tpm2-software/tpm2-openssl/blob/master/docs/keys.md#key-generation
To set that you need something like
OSSL_PARAM params[3];
EVP_PKEY *pkey = NULL;
EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", "provider=tpm2");
params[0] = OSSL_PARAM_construct_size_t(OSSL_PKEY_PARAM_RSA_BITS, &bits);
params[1] = OSSL_PARAM_construct_utf8_string("parent-auth", "password", 0);
params[2] = OSSL_PARAM_construct_end();
if (EVP_PKEY_keygen_init(pctx) && EVP_PKEY_CTX_set_params(pctx, params))
EVP_PKEY_generate(pctx, &pkey);
Hi, I'm trying to load the key from the specific handler (handle:0x81010002), I'm not generating new RSA Private key. Is there any APIs to load the key from the handler and convert to EVP_PKEY structure.
For Ex, Load the Private Key, openssl rsa -provider-path /usr/lib64/ossl-packages/ -provider tpm2 -out privatekey.pem -in handle:0x81010002?pass -passin pass:ynM67sdZjEJesWk6
Convert the privatekey.pem to EVP_PKEY Structure And the content of Private key is, -----BEGIN TSS2 PRIVATE KEY----- MIIBNQYGZ4EFCgEDoAMBAQECBEAAAAEEggEYARYAAQALAAYAcgAAABAAEAgAAAAA AAEA1ulSPzuYEDTez5D8VOczFDVMRliHQ748NB9KYSlKn0H7QPO3gpHOrzR6tNS8 mNki3MtoizWb8LU9fq5J98rLJzC1kzisF4tjYXqs+QcK7MU1HfeGxa+dwtY8d6jI Z2uew5i3u3nVPl/07tCwPXdv9FRjl5JoNPpADu7zmVMggwAEN6E+xw6PfouMWCwS 7R3p5IZFRZQn+lrX8xPPbcB7ImxfPjqx16PhknSng7PyQNMBkJNO0pA+20SxP4aP WkG0SwbLJM+9QJQ6x9dpyTIK0pl4XJyryuE7yvv/qxZqeL6eThLFhaOlfwYROdsH E2dsWX1sLdgNwVEy3sno6aR+CQQEAAIBgQ== -----END TSS2 PRIVATE KEY-----
Can you help us here?
Well, without password it looks like this:
OSSL_STORE_CTX *ctx;
if (ctx = OSSL_STORE_open("handle:0x81010002", NULL, NULL, NULL, NULL)) {
while (OSSL_STORE_eof(ctx) == 0) {
OSSL_STORE_INFO *info = OSSL_STORE_load(ctx);
if (info && OSSL_STORE_INFO_get_type(info) == OSSL_STORE_INFO_PKEY) {
EVP_PKEY *pkey = OSSL_STORE_INFO_get0_PKEY(info);
OSSL_STORE_INFO_free(info);
}
}
}
It requires password also
I added a new example that demonstrates the use of OSSL_STORE_open
with a password:
https://github.com/tpm2-software/tpm2-openssl/blob/master/test/ec_genpkey_store_load.c
Hi, This is the overall Code for loading the TPM2TSS Private key in EVP_PKEY Structure.
code:
int main() { const char password = "Aw2WLz9bHAideywh"; OSSL_PROVIDER defprov = NULL; OSSL_STORE_CTX ctx = NULL; OSSL_STORE_INFO info = NULL; UI_METHOD ui_method = NULL; std::string tpm_key_path = "handle:0x81010002"; std::string vendor_key_password = "ynM67sdZjEJesWk6"; OSSL_PARAM params[3]; EVP_PKEY pkey = NULL; BIO out = BIO_new_fp( stdout, BIO_NOCLOSE ); if ( ( defprov = OSSL_PROVIDER_load( NULL, "/usr/lib64/ossl-packages/tpm2.so" ) ) ) { if ( ( ctx = OSSL_STORE_open( tpm_key_path.c_str(), nullptr, (void )password, nullptr, nullptr ) ) ) { while ( !OSSL_STORE_eof( ctx ) ) { OSSL_STORE_INFO *info = OSSL_STORE_load( ctx ); if ( ( info && OSSL_STORE_INFO_get_type( info ) == OSSL_STORE_INFO_PKEY ) ) { pkey = OSSL_STORE_INFO_get0_PKEY( info ); EVP_PKEY_print_private(out, pkey, 0, NULL); BIO_free(out); std::cout <<"true\n"; OSSL_STORE_INFO_free( info ); } } } } if ( pkey ) { std::cout << "not empty\n"; } ERR_print_errors_fp(stderr); OSSL_STORE_close(ctx); OSSL_PROVIDER_unload(defprov); return 0; }
This is the output generated:
PROVIDER INIT
STORE/OBJECT OPEN handle:0x81010002
STORE/OBJECT LOAD
STORE/OBJECT LOAD pkey
STORE/OBJECT LOAD found RSA
RSA LOAD
RSA GET_PARAMS [ bits security-bits max-size ]
RSA HAS 1
ENCODER tss PrivateKeyInfo/der DOES_SELECTION 0x87
ENCODER tss PrivateKeyInfo/pem DOES_SELECTION 0x87
ENCODER rsa pkcs1/der DOES_SELECTION 0x87
ENCODER rsa pkcs1/der DOES_SELECTION 0x87
ENCODER rsa pkcs1/der DOES_SELECTION 0x87
ENCODER rsa pkcs1/der DOES_SELECTION 0x87
ENCODER rsa pkcs1/pem DOES_SELECTION 0x87
ENCODER rsa pkcs1/pem DOES_SELECTION 0x87
ENCODER rsa pkcs1/pem DOES_SELECTION 0x87
ENCODER rsa pkcs1/pem DOES_SELECTION 0x87
ENCODER rsa SubjectPublicKeyInfo/der DOES_SELECTION 0x87
ENCODER rsa SubjectPublicKeyInfo/der DOES_SELECTION 0x87
ENCODER rsa SubjectPublicKeyInfo/der DOES_SELECTION 0x87
ENCODER rsa SubjectPublicKeyInfo/der DOES_SELECTION 0x87
ENCODER rsa SubjectPublicKeyInfo/pem DOES_SELECTION 0x87
ENCODER rsa SubjectPublicKeyInfo/pem DOES_SELECTION 0x87
ENCODER rsa SubjectPublicKeyInfo/pem DOES_SELECTION 0x87
ENCODER rsa SubjectPublicKeyInfo/pem DOES_SELECTION 0x87
ENCODER ENCODE rsa text
Private-Key: (RSA 2048 bit, TPM 2.0)
Modulus:
00:c2:51:73:e2:b3:a8:34:9c:5d:13:de:6b:19:69:
88:3c:ef:d1:74:86:6c:43:a5:72:87:b9:e3:d6:60:
82:84:e8:24:f9:78:d1:8f:f8:e5:a2:82:d9:aa:f4:
18:b7:fa:83:5b:88:a7:d8:ab:82:d9:b7:52:b0:e1:
4d:c7:c7:1e:fb:4a:3a:6e:0a:8f:c6:31:d8:4a:12:
8e:a0:0b:b4:ea:62:62:70:10:12:80:60:c4:17:0b:
de:30:68:b5:76:34:aa:52:8a:79:e8:88:38:82:53:
60:a2:63:b4:23:bb:13:c0:c0:cc:a6:72:c3:3e:74:
9e:e3:e1:22:b6:20:96:de:30:ca:e5:4e:8a:ad:83:
3a:a3:fc:81:a9:c0:26:79:ea:76:15:06:15:4d:7a:
5c:00:d5:25:c4:89:d7:c4:80:96:dd:8c:33:c9:62:
80:82:0a:0b:ef:a8:d5:97:74:4e:d6:b6:39:d1:08:
32:dc:1b:1c:d6:66:99:b3:f1:73:14:75:a4:b4:04:
2e:36:3f:14:bb:15:37:ab:84:17:cc:84:2e:90:bf:
b2:bb:5e:75:4b:71:e5:ef:79:6b:8a:df:36:85:a4:
33:51:a1:41:03:3e:3f:4a:3f:22:a8:91:b2:e3:61:
aa:db:da:e4:19:ba:59:0c:b0:a3:4c:10:31:85:16:
6d:e7
Exponent: 65537 (0x10001)
Object Attributes:
fixedTPM
fixedParent
sensitiveDataOrigin
userWithAuth
decrypt
sign / encrypt
Signature Scheme:
so, Is this pkey is of EVP_PKEY format? And also i want to confirm whether pkey generated can be stored in pem file which will be later used to parse the file using PEM_read_PrivateKey in EVP_PKEY format? Let us know if i'm on the right track.
Yes, it's the EVP_PKEY structure. The TPM-based private key can be stored in a PEM file, which can be later loaded using OSSL_STORE_load
. The PEM_read_PrivateKey
doesn't work for TPM handles, but the OSSL_STORE_load
loads the PEM into the EVP_PKEY structure.
**Can you share the full code using OSSL_STORE_load?**
Sorry, I didn't check it properly. Thanks for your support!
I'm trying to free pkey data using EVP_PKEY_free(pkey); but it got hung and the process is not finished. I had to abort the process manually. Can you let me know how to free it?
As you said: EVP_PKEY_free(pkey) is the right function.
But it is not freeing up , and there is no PROVIDER TEARDOWN and got hung It is getting hung, RSA FREE STORE/OBJECT CLOSE
without using EVP_PKEY_free(pkey); It is getting exited successfully RSA FREE STORE/OBJECT CLOSE not empty PROVIDER TEARDOWN
code: EVP_PKEY tpmPrivateKeyEvpPkeyFormat( ) { std::string vendorKeyPassword; OSSL_PROVIDER defprov = NULL; OSSL_STORE_CTX ctx = NULL; OSSL_STORE_INFO info = NULL; std::string tpm_key_path = std::string( "handle:" ) + TPM_PERSISTENT_HANDLE; EVP_PKEY pkey = NULL; if ( checkPersistentValue( TPM_PERSISTENT_HANDLE ) ) { if ( fetchVendorPassowrd( vendorKeyPassword ) ) { std::cout << "vendorKeyPassword is " << vendorKeyPassword << "\n"; BIO out = BIO_new_fp( stdout, BIO_NOCLOSE ); if ( ( defprov = OSSL_PROVIDER_load( NULL, "/usr/lib64/ossl-packages/tpm2.so" ) ) ) { if ( ( ctx = OSSL_STORE_open( tpm_key_path.c_str(), nullptr, (void )vendorKeyPassword.c_str(), nullptr, nullptr ) ) ) { while ( !OSSL_STORE_eof( ctx ) ) { OSSL_STORE_INFO info = OSSL_STORE_load( ctx ); if ( ( info && OSSL_STORE_INFO_get_type( info ) == OSSL_STORE_INFO_PKEY ) ) { pkey = OSSL_STORE_INFO_get0_PKEY( info ); // EVP_PKEY_print_public( out, pkey, 0, NULL ); // std::cout << "=======================\n"; EVP_PKEY_print_private( out, pkey, 0, NULL ); BIO_free( out ); std::cout <<"true\n"; OSSL_STORE_INFO_free( info ); } } } } ERR_print_errors_fp( stderr ); OSSL_STORE_close( ctx ); OSSL_PROVIDER_unload( defprov ); } } return pkey; }
and in main() EVP_PKEY *pkey = tpmPrivateKeyEvpPkeyFormat( ); if ( pkey ) { std::cout << "not empty\n"; } EVP_PKEY_free(pkey); return 0;
Let me know if i'm making mistake, eventually it should free it, but it's not happening?
Then OSSL_PROVIDER_load and unload must be in main the first and the last command. You must not free the provider before freeing the key handled by that provider.
It is still the same, Can you help me by correcting the code ? EVP_PKEY tpmPrivateKeyEvpPkeyFormat( OSSL_PROVIDER defprov ) { std::string vendorKeyPassword; OSSL_STORE_CTX ctx = NULL; OSSL_STORE_INFO info = NULL; std::string tpm_key_path = std::string( "handle:" ) + TPM_PERSISTENT_HANDLE; EVP_PKEY pkey = NULL; if ( checkPersistentValue( TPM_PERSISTENT_HANDLE ) ) { if ( fetchVendorPassowrd( vendorKeyPassword ) ) { std::cout << "vendorKeyPassword is " << vendorKeyPassword << "\n"; BIO out = BIO_new_fp( stdout, BIO_NOCLOSE ); if ( defprov ) { if ( ( ctx = OSSL_STORE_open( tpm_key_path.c_str(), nullptr, (void )vendorKeyPassword.c_str(), nullptr, nullptr ) ) ) { while ( !OSSL_STORE_eof( ctx ) ) { OSSL_STORE_INFO info = OSSL_STORE_load( ctx ); if ( ( info && OSSL_STORE_INFO_get_type( info ) == OSSL_STORE_INFO_PKEY ) ) { pkey = OSSL_STORE_INFO_get0_PKEY( info ); // EVP_PKEY_print_public( out, pkey, 0, NULL ); // std::cout << "=======================\n"; EVP_PKEY_print_private( out, pkey, 0, NULL ); BIO_free( out ); std::cout <<"true\n"; OSSL_STORE_INFO_free( info ); } } } } ERR_print_errors_fp( stderr ); OSSL_STORE_close( ctx ); } } return pkey; }
int main() { OSSL_PROVIDER defprov = NULL; defprov = OSSL_PROVIDER_load( NULL, "/usr/lib64/ossl-packages/tpm2.so" ); EVP_PKEY pkey = tpmPrivateKeyEvpPkeyFormat( defprov ); if ( pkey ) { std::cout << "not empty\n"; } if ( defprov) { std::cout << " not defprov\n"; } EVP_PKEY_free(pkey); if ( !pkey ) { std::cout << "empty\n"; } OSSL_PROVIDER_unload( defprov ); // return 0; }
Try OSSL_STORE_INFO_get1_PKEY instead OSSL_STORE_INFO_get0_PKEY. You should read the man pages to understand the difference.
I'm a newbie to this, I'm not able to understand it. So I'm requesting for your help
I can help, but as a newbie you should learn and try to understand what you are doing, otherwise you will never improve. :-)
I tried it, but still it was holding something and it was not NULL
The pkey will not be NULL after calling EVP_PKEY_free(pkey);
I really appreciate your help, Thank You So much.
Hi, Do we have cmp support for tpm2 tss key format. I'm trying to set a private key (EVP_PKEY) which is of TSS2 PRIVATE KEY format. in the context of a CMP operation., by using OSSL_CMP_CTX_set1_pkey(cmpCtx, privatekey) api . But it is not able to do it. We are getting the following error when we use the TSS2 EVP_PKEY for CMP IR request -
00B7AA37EF7F0000:error:068000DE:asn1 encoding routines:asn1_template_ex_i2d:illegal zero content:crypto/asn1/tasn_enc.c:374: 00B7AA37EF7F0000:error:0488000D:PEM routines:PEM_ASN1_write_bio:ASN1 lib:crypto/pem/pem_lib.c:341: 00B7AA37EF7F0000:error:020000B3:rsa routines:rsa_ossl_private_encrypt:missing private key:crypto/rsa/rsa_ossl.c:332: 00B7AA37EF7F0000:error:1C880004:Provider routines:rsa_sign:RSA lib:providers/implementations/signature/rsa_sig.c:588: 00B7AA37EF7F0000:error:06880006:asn1 encoding routines:ASN1_item_sign_ctx:EVP lib:crypto/asn1/a_sign.c:284: 00B7AA37EF7F0000:error:1D00007F:CMP routines:ossl_cmp_msg_protect:error protecting message:crypto/cmp/cmp_protect.c:332: 00B7AA37EF7F0000:error:1D0000A3:CMP routines:ossl_cmp_certreq_new:error creating certreq:crypto/cmp/cmp_msg.c:439:
So is there any API which supports this format TSS2 PRIVATE KEY?
This test demonstrates that CMP is supported to a certain extent: https://github.com/tpm2-software/tpm2-openssl/blob/master/test/rsa_genpkey_x509_cmp.sh
Please create a short script or .c file that I can build and execute to reproduce the error you are getting.
Hi, Sorry for the above mis info, Creating CMP ctx, OSSL_CMP_CTX *cmp_ctx=NULL; cmp_ctx = OSSL_CMP_CTX_new(NULL, NULL);
we are trying to send IR using cmp_ctx , in the cmp_ctx we have the private key of the application that is generated by RSA.
secondly, we have the cmp server details and end entity subject name, and other details required for IR.
In the same ctx also we also have vendor private key (TPM BASED) and setting the vendor private key using the OSSL_CMP_CTX_set1_pkey (cmp_ctx, vendorprivatekey) api and also setting the vendor end entity cert and ca details.
we use the OSSL_CMP_exec_IR_ses( cmp_ctx) api to send the IR to cmp sever , here the issue comes when using this api
These are the errors we are facing while sending the IR request, 00B7AA37EF7F0000:error:068000DE:asn1 encoding routines:asn1_template_ex_i2d:illegal zero content:crypto/asn1/tasn_enc.c:374: 00B7AA37EF7F0000:error:0488000D:PEM routines:PEM_ASN1_write_bio:ASN1 lib:crypto/pem/pem_lib.c:341: 00B7AA37EF7F0000:error:020000B3:rsa routines:rsa_ossl_private_encrypt:missing private key:crypto/rsa/rsa_ossl.c:332: 00B7AA37EF7F0000:error:1C880004:Provider routines:rsa_sign:RSA lib:providers/implementations/signature/rsa_sig.c:588: 00B7AA37EF7F0000:error:06880006:asn1 encoding routines:ASN1_item_sign_ctx:EVP lib:crypto/asn1/a_sign.c:284: 00B7AA37EF7F0000:error:1D00007F:CMP routines:ossl_cmp_msg_protect:error protecting message:crypto/cmp/cmp_protect.c:332: 00B7AA37EF7F0000:error:1D0000A3:CMP routines:ossl_cmp_certreq_new:error creating certreq:crypto/cmp/cmp_msg.c:439:
With pre-shared keys and reference number the same solution is working. On replacing the pre-shared key and reference number with vendor certificates we are seeing the errors Let us know, are we making any mistake here?
Please try to reproduce the issue with a small .c file that you can share with me and I can then build and run.
Hi,
I'm Sharing the code in c++ , file name is opensource_tpm.cpp
To create the executable file,
run
g++ opensource_tpm.cpp -o opensource_tpm -lssl -lcrypto
and run ./opensource_tpm binary for performing IR request using cmp api's
This is the code: opensource_tpm.txt Save the above file as opensource_tpm.cpp
CodeLink: https://github.com/tpm2-software/tpm2-openssl/files/13224218/opensource_tpm.txt
serialNo.txt rsa_private_key.txt
Pem Files Link: https://github.com/tpm2-software/tpm2-openssl/files/13224256/serialNo.txt https://github.com/tpm2-software/tpm2-openssl/files/13224257/rsa_private_key.txt
Save the serialNo.txt as serialNo.pem, rsa_private_key.txt as rsa_private_key.pem and change the path in the code after placing the pem files in appropriate location and execute the code for sending IR Request using CMP Protocol
Performed TPM Steps Link: [TPM_CSR_GENERATION.txt] https://github.com/tpm2-software/tpm2-openssl/files/13224422/TPM_CSR_GENERATION.txt This below TPM_CSR_GENERATION file will give info on how we are generating the private key and also the CSR file by persisting the handle. Let us know, are we making any mistake here.
This is the output: It is failing with tpm private key only
-----BEGIN PRIVATE KEY----- MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCS5IpPJtvBar9I 02OohNtjWxu/ySob7fPmjALtOLCxpjEr0b4GMfcwyL+/a7+hRvs583grBXOIgcQK KzsXp1GQ5V1+Nfz0YveucWKI0+lQK/u7NbIgYGQ422QorfJv9XIUMhN1Zp0+h/2l cmp2x+nY2fQ1U8x/Tl2DdqSNSlng9zAkXqozEdbPpFi7tuWk6gidVxYbyrWQPkI3 wj/uHBKGe9QB8Vmc7zRgQ4TGkYO46l31r8Q+ITKJZZU3FNwHJj+PXTOhAivaI1yF GheyX6MzrCNRxw0mmPZRZjYZiU/wxNwekkp+BfBoRVhaBO9kftfJhgSHfSoCmU6A Edk1+VLDAgMBAAECggEABBjLV2V3jT+bbH4M0lc7loak0aaxfcxCAwTrqKRt9Ske nPYWwoMj6Es+YdSGUzVbbg8sI6hdbl9kJtPJgaGL2lUzVCulovFHBClVvLLgV86U 5kXwnQuN2rIaazIIHXbvLWtaHz+d6hpj3iNAnzsjJVuq086YWQKdWWchNBmbQ8rG Tm7Obl/jEHYx7MhyXbgj/FpA0PB3zEI9+s2Sw9DyYpbVpW8fJy2kplfjQXxCPXpn 5xsANKy/+tSm6/Qs0Qx7yM1QTav+/35irOns6alK5vlEOjFtXsa4Xq+e0ATdkeww 5iYVs8eQ+sms82LKOH+q49reeo/1r4Qs1ghhl/TeVQKBgQDETjdiPMuoCtIKw83/ nmt/XQYy6M0Fr3mabx6W0MI/olH8ZEDmSu0+v3S0feWtOYCNJB90ItSd+Qi/6Lck C26c+aacvwUfAvGv7YXp2uzrRnurbrIJBI5T3BI0aLXAxzizMNJNE52dr5igcmZF PLpGOWt9Er7mUJbp650ks9k0nwKBgQC/j7BwV81kenY7t6pFuxKp9JT6X/q2bcys 3bvVjSgHYlLYiRA8qAHv107VsZ5EepuNbS4W9lqQd7exz3AfIHyf6DdVUKNL+/Os 7HZZFWT17yxU8tcUNgKhg69wvG0YbI0kVEwFRx9RP3UVIIra5rosXnDNzB+vitAi Hgfu+zWrXQKBgEW7QxEyZ2WZ8mLAizxyGd10Pe93otySKLAjKMqJ/XZ9QoJVWnhz xTK078/tqNiPxIpeeo3WkZBMFj+Vevji1rgMNpMXh8osUY4c4aTgj6hDsUqEV9m8 NJK1agIT7/w6yHlerlWS0jphVeYovQt7NvAbFYOoVQebOQB/IaMX/+AhAoGBALc1 3jIUR8TJuzryNk/q07bozXOJSGgiK5dJmtRr5NTrHQEsVfMtXGzfJ+8Jqa0k9pEU 0vfzNjrlxTKyizG6CHeHySQ3s3aAylWg8q/Q3na5AVVdzIbwASQopirUjCLH71XH qc2CcFlsr7Y9IZCrC3RT/t9VUxi5UsbOohfW+0WhAoGAWEdjkznjlGvhfLWf5oc8 dM7GAJQZfdcOoS/tXNy6xFtEc9cxOTGL6x9NQug8JE7SdTQCuOuC1jD+qYZobYxL RdBVitxddgVt5hSCmscd2jVPbI9shOGUlxnfTZOcHIdYYxkoOV+S8YJ3ZbKV5jj0 Og/i0snZlTz7pto/khEDvxo= -----END PRIVATE KEY-----
PROVIDER INIT vendorKeyPassword is Aw2WLz9bHAideywh STORE/OBJECT OPEN handle:0x81010002?pass STORE/OBJECT LOAD tpm_password_callback is Aw2WLz9bHAideywh size is 64 STORE/OBJECT LOAD pkey STORE/OBJECT LOAD found RSA RSA LOAD RSA GET_PARAMS [ bits security-bits max-size ] RSA HAS 1 fetched pkey STORE/OBJECT CLOSE -----BEGIN CERTIFICATE----- MIIEvzCCAqegAwIBAgIFARJ0fjMwDQYJKoZIhvcNAQELBQAwOjEOMAwGA1UECgwFTm9raWExKDAm BgNVBAMMH0ZhY3RvcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMjMxMDMxMTAyNDI2WhcN NDExMDI2MTA1NDI2WjBdMSUwIwYDVQQKDBxOb2tpYSBTb2x1dGlvbnMgYW5kIE5ldHdvcmtzMTQw MgYDVQQDDCtRVEZDV04yMjQwMDY2Lm5va2lhc29sdXRpb25zYW5kbmV0d29ya3MuY29tMIIBIjAN BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtQ6/Up8Vkq/hGXV7yUWvyrw9ZPXRrWvYVCMz30mr AZV7ofcSBqktQ2vtroNPBliMa2Vvi6tgR8KpWJIfLUIG3c8dZpXq0G7fsg75CkEsaqeXDJtXVtIt bO59CVbW3ZTR3vDhRRinbYLDgjbMWaOetGirPVcClbI8BNg1WI89f8Ig0VjQPPrxAsfbEIazDro1 FYsXTnEnp3ztp+kZkqg2L6V5Rf2REWQvc3IyKHktABuCJHGeq9qEWWmGTkCLzRLguSAmGHxWOAEW 6cPSdebaiDsWe5UL342tMgPvRVmocj3EGav1hwnkq0HIpLuO1KKnjyB8hSo+FVI2bfEomCFsiwID AQABo4GoMIGlMB8GA1UdIwQYMBaAFMwqtHm2sKHPYIy+6B9zT8Xz9BHPMB0GA1UdDgQWBBTOSqKk +cs2N8YvsfYk+NsbWQQ5YzAOBgNVHQ8BAf8EBAMCBaAwGwYDVR0gBBQwEjAQBg4rBgEEAYHeKgEP AQICATA2BgNVHREELzAtgitRVEZDV04yMjQwMDY2Lm5va2lhc29sdXRpb25zYW5kbmV0d29ya3Mu Y29tMA0GCSqGSIb3DQEBCwUAA4ICAQAV3sHaLsIAANn3odNoJW9WaN8U9K8vvQafi7/P5G4p7JSo Mg5j9P8DN3V+8SmVnGlHPHhSFM+bQffvQYbQtcqbFDZAVAuGV9sLZ9rnPrsm0vziHKbzPz8ZW74P T2WXHoIPwzDdweRe1ELKzjQV1f31Eoe+fnrQIUK/YWCzAOQyqKmB+KGnhQMhJjZDpplmir3/Dcf+ cAbMu4eZtV+aIGTvgkDqwVFkm/JMsb63GKdRPywHHjARujixL8jRxta2cMxAQOZaUBiUEd4/Yui8 Tqpm51oI9mUH+g6pCQU21zq52q6bhJjJIgOkmL81UnK+nk65nUHHoxTun9ySyZSLH52aMlUE9rl5 28untgtqjSwhXIBM4Qm62acQMas8FF1rVSK/QKa5dPsmlc+mzN0sBODFUL6p92zbt0TNLNXU9utH 0vDCnEj1rxEz2WFQcB7riXyjNcNf+Z9b+oyAebIGaq4Qykl7rB4M1hhwXT7jWQcSWV0a4voJmoGf 16oXaeNP5pbGUQOK+5RKW3X2Xhesk9LlvhFgnBtHX9OU+NzFbbPyZdmjcjLHpmRgsFlNfJ5Ih8AG X/2juXwjea4DitQAJvixgxb8Xsru4MbnsC0PrkkRitBBu+sX0UY0enC89FvgXK8VoLIWoT8HqnCU 9gff38Az0i3ltXFZ/FKqgohu1PJIeA== -----END CERTIFICATE-----
DIGEST SHA1 GET_PARAMS [ blocksize size xof algid-absent ] DIGEST SHA256 GET_PARAMS [ blocksize size xof algid-absent ] DIGEST SHA384 GET_PARAMS [ blocksize size xof algid-absent ] ENCODER tss PrivateKeyInfo/der DOES_SELECTION 0x86 ENCODER tss PrivateKeyInfo/der DOES_SELECTION 0x86 ENCODER tss PrivateKeyInfo/der DOES_SELECTION 0x86 ENCODER tss PrivateKeyInfo/der DOES_SELECTION 0x86 ENCODER tss PrivateKeyInfo/pem DOES_SELECTION 0x86 ENCODER tss PrivateKeyInfo/pem DOES_SELECTION 0x86 ENCODER tss PrivateKeyInfo/pem DOES_SELECTION 0x86 ENCODER tss PrivateKeyInfo/pem DOES_SELECTION 0x86 ENCODER rsa pkcs1/der DOES_SELECTION 0x86 ENCODER rsa pkcs1/pem DOES_SELECTION 0x86 ENCODER rsa SubjectPublicKeyInfo/der DOES_SELECTION 0x86 ENCODER rsa SubjectPublicKeyInfo/pem DOES_SELECTION 0x86 ENCODER rsa SubjectPublicKeyInfo/der ENCODE 0x86 RSA GET_PARAMS [ default-digest mandatory-digest ] RSA EXPORT 87 IR is failed failed code is -1 failed cmp ctx CMP error: missing private key CMP error: RSA lib CMP error: EVP lib CMP error: error creating certreq RSA FREE
Hmm, there are bugs in the key generation guideline and the .cpp file:
One this is fixed the CMP feels correct, but it fails for me because the peer server is not accessible.
I couldn't understand what you mean by generate a certificate. can you elaborate more on this, and also can you share any example? And also for the password, the guide is just an reference on how i generated in another machine, and the password in the .cpp file it is different. can you tell me what password I have to pass from the guide I shared?
It's ynM67sdZjEJesWk6
that should be used as a password, not Aw2WLz9bHAideywh
. Also, there are no steps how to generate the serialNo.pem
file, which is required and must match the TPM key, so I couldn't use the one you supplied.
Hi, This is how I generated the key pair and persisted it with the correct password. echo Jz7AATQApZAx3OdGrikOqohgI6Ux5MGktKbhiExFJdbvLFE9dlPLuaRmA4VYg8fLcBhFDQaAcmpxZvguAqbwCM3ZZVhN1iSlhAZD75SYuo4o8n9tm5cm44OAnLB7M5m2QQkdZZqsMQ6FpPOAHBFoEwI2Y1PFAB0dponCuAUIfPSlZXgmKILvJvc54HQALadted4C9gbrYS6ZyjfU9GNNckaoegqVWnFSvoCDEcaRTeExkKeHBZNfkIP79VPZYSh |tpm2 createprimary -C e -G rsa2048 -a 'restricted|decrypt|fixedtpm|fixedparent|sensitivedataorigin|userwithauth' -u - -c /working_dir/endorsementkey.ctx -P GosKS1xXvgkM6bSm -p qx2lAO8Jf4RbXJBb
tpm2_evictcontrol -C o -c /working_dir/endorsementkey.ctx 0x81010001 -P vMHuwlrSsGXNSXER
tpm2_create -C 0x81010001 -a 'fixedtpm|fixedparent|sensitivedataorigin|userwithauth|decrypt|sign' -u /working_dir/vendorkey.pub -r /working_dir/vendorkey.priv -P qx2lAO8Jf4RbXJBb -p Aw2WLz9bHAideywh
tpm2_load -C 0x81010001 -u /working_dir/vendorkey.pub -r /working_dir/vendorkey.priv -c /working_dir/vendorkey.ctx -P qx2lAO8Jf4RbXJBb
tpm2_evictcontrol -C o -c /working_dir/vendorkey.ctx 0x81010002 -P vMHuwlrSsGXNSXER
And CSR File is generated using,
openssl req -new -provider-path /usr/lib64/ossl-packages/ -provider tpm2 -key handle:0x81010002?pass -passin pass:Aw2WLz9bHAideywh -out /working_dir/vendorkey.csr -config /config/csr.cnf
And tpm_private_key is generated using,
openssl rsa -provider-path /usr/lib64/ossl-packages/ -provider tpm2 -out tpm_privatekey.pem -in handle:0x81010002?pass -passin pass:Aw2WLz9bHAideywh
And tpm_public_key is generated using,
openssl rsa -provider-path /usr/lib64/ossl-packages/ -provider tpm2 -pubout -out tpm_publickey.pem -in handle:0x81010002?pass -passin pass:Aw2WLz9bHAideywh
And serialNo.pem is generated using,
We have serialNo.pem generated by using the vendorkey.csr from above and then CSR File is sent to the ca server to get it. And CA Server directly we cannot access it directly.
And rsa_private_key.pem,
openssl genrsa -out rsa-private.pem 2048
Attached the keys and pem files generated in the below link,
TPM_PEM_FILES.zip Link for files: https://github.com/tpm2-software/tpm2-openssl/files/13295681/TPM_PEM_FILES.zip
Prerequisite for sending IR using cmp:
I tried the same using the cmp command and IR is being Sent, but failed to send IR using the above c++ code. Command: openssl cmp -provider-path /usr/lib64/ossl-packages/ -provider tpm2 -provider default -propquery '?provider=tpm2,tpm2.digest!=yes' -cmd ir -server 10.33.123.231:8081/pkix/ -recipient "/CN=CMPserver" -cert /working_dir/serialNo.pem -key handle:0x81010002?pass -keypass pass:Aw2WLz9bHAideywh -subject "/CN=Client" -certout test-my-cert.pem -cacertsout test-my-ca.pem console: cmp_main:apps/cmp.c:2833:CMP info: using section(s) 'cmp' of OpenSSL configuration file '/etc/pki/tls/openssl.cnf' cmp_main:apps/cmp.c:2842:CMP info: no [cmp] section found in config file '/etc/pki/tls/openssl.cnf'; will thus use just [default] and unnamed section if present PROVIDER INIT DIGEST SHA1 GET_PARAMS [ blocksize size xof algid-absent ] DIGEST SHA256 GET_PARAMS [ blocksize size xof algid-absent ] DIGEST SHA384 GET_PARAMS [ blocksize size xof algid-absent ] STORE/OBJECT OPEN handle:0x81010002?pass STORE/OBJECT SET_PARAMS [ properties ] STORE/OBJECT SET_PARAMS [ expect ] STORE/OBJECT LOAD STORE/OBJECT LOAD pkey STORE/OBJECT LOAD found RSA RSA LOAD RSA GET_PARAMS [ bits security-bits max-size ] RSA HAS 1 STORE/OBJECT CLOSE setup_protection_ctx:apps/cmp.c:1448:CMP warning: will not authenticate server due to missing -secret, -trusted, or -srvcert DER DECODER DECODE setup_client_ctx:apps/cmp.c:2009:CMP info: will contact http://10.33.123.231:8081/pkix/ RAND NEW RAND NEW RAND GET_CTX_PARAMS [ max_request ] RAND GENERATE RAND GET_CTX_PARAMS [ max_request ] RAND GENERATE ENCODER tss PrivateKeyInfo/der DOES_SELECTION 0x86 ENCODER tss PrivateKeyInfo/der DOES_SELECTION 0x86 ENCODER tss PrivateKeyInfo/der DOES_SELECTION 0x86 ENCODER tss PrivateKeyInfo/der DOES_SELECTION 0x86 ENCODER tss PrivateKeyInfo/pem DOES_SELECTION 0x86 ENCODER tss PrivateKeyInfo/pem DOES_SELECTION 0x86 ENCODER tss PrivateKeyInfo/pem DOES_SELECTION 0x86 ENCODER tss PrivateKeyInfo/pem DOES_SELECTION 0x86 ENCODER rsa pkcs1/der DOES_SELECTION 0x86 ENCODER rsa pkcs1/der DOES_SELECTION 0x86 ENCODER rsa pkcs1/der DOES_SELECTION 0x86 ENCODER rsa pkcs1/der DOES_SELECTION 0x86 ENCODER rsa pkcs1/pem DOES_SELECTION 0x86 ENCODER rsa pkcs1/pem DOES_SELECTION 0x86 ENCODER rsa pkcs1/pem DOES_SELECTION 0x86 ENCODER rsa pkcs1/pem DOES_SELECTION 0x86 ENCODER rsa SubjectPublicKeyInfo/der DOES_SELECTION 0x86 ENCODER rsa SubjectPublicKeyInfo/der DOES_SELECTION 0x86 ENCODER rsa SubjectPublicKeyInfo/der DOES_SELECTION 0x86 ENCODER rsa SubjectPublicKeyInfo/der DOES_SELECTION 0x86 ENCODER rsa SubjectPublicKeyInfo/pem DOES_SELECTION 0x86 ENCODER rsa SubjectPublicKeyInfo/pem DOES_SELECTION 0x86 ENCODER rsa SubjectPublicKeyInfo/pem DOES_SELECTION 0x86 ENCODER rsa SubjectPublicKeyInfo/pem DOES_SELECTION 0x86 RSA GET_PARAMS [ default-digest mandatory-digest ] SIGN DIGEST_INIT rsa MD=SHA2-256 SIGN GET_CTX_PARAMS [ algorithm-id ] SIGN DIGEST_SIGN estimate SIGN DIGEST_SIGN RSA HAS 2 RSA NEW RSA IMPORT [ n e ] RSA MATCH 0x6 SIGN DIGEST_INIT rsa MD=SHA256 SIGN GET_CTX_PARAMS [ algorithm-id ] SIGN DIGEST_SIGN estimate SIGN DIGEST_SIGN CMP info: sending IR CMP error: Connection timed out:calling connect() CMP error: connect error CMP error: Connection timed out:calling connect(10.33.123.231, 8081) CMP error: connect error CMP error: transfer error:request sent: IR, expected response: IP RSA FREE RSA FREE RAND FREE RAND FREE PROVIDER TEARDOWN
Yeah. The error above is connect error
because the Connection timed out
, so this is connectivity related, not a TPM2 issue. It seems the tpm2 provider works correctly in this case.
The connection timeout error is expected, but my doubt is why through the openssl cmp command it is trying to send IR and failing to connect which is expected, and when i'm trying to achieve the same in c++ programatically, it fails to send IR. O/p is: IR is failed failed code is -1 failed cmp ctx CMP error: missing private key CMP error: RSA lib CMP error: EVP lib CMP error: error creating certreq Anything wrong in our program or anything we are missing while loading the providers or setting of the cmp ctx using apis?
As I wrote, the passwords are wrong. I tried to build and execute the code and reached the connectivity error. I didn't get the key related error.
Hi, This is how I generated the key pair and persisted it with the correct password.
echo Jz7AATQApZAx3OdGrikOqohgI6Ux5MGktKbhiExFJdbvLFE9dlPLuaRmA4VYg8fLcBhFDQaAcmpxZvguAqbwCM3ZZVhN1iSlhAZD75SYuo4o8n9tm5cm44OAnLB7M5m2QQkdZZqsMQ6FpPOAHBFoEwI2Y1PFAB0dponCuAUIfPSlZXgmKILvJvc54HQALadted4C9gbrYS6ZyjfU9GNNckaoegqVWnFSvoCDEcaRTeExkKeHBZNfkIP79VPZYSh |tpm2 createprimary -C e -G rsa2048 -a 'restricted|decrypt|fixedtpm|fixedparent|sensitivedataorigin|userwithauth' -u - -c /working_dir/endorsementkey.ctx -P GosKS1xXvgkM6bSm -p qx2lAO8Jf4RbXJBb
tpm2_evictcontrol -C o -c /working_dir/endorsementkey.ctx 0x81010001 -P vMHuwlrSsGXNSXER
tpm2_create -C 0x81010001 -a 'fixedtpm|fixedparent|sensitivedataorigin|userwithauth|decrypt|sign' -u /working_dir/vendorkey.pub -r /working_dir/vendorkey.priv -P qx2lAO8Jf4RbXJBb -p Aw2WLz9bHAideywh
tpm2_load -C 0x81010001 -u /working_dir/vendorkey.pub -r /working_dir/vendorkey.priv -c /working_dir/vendorkey.ctx -P qx2lAO8Jf4RbXJBb
tpm2_evictcontrol -C o -c /working_dir/vendorkey.ctx 0x81010002 -P vMHuwlrSsGXNSXER
And CSR File is generated using,
openssl req -new -provider-path /usr/lib64/ossl-packages/ -provider tpm2 -key handle:0x81010002?pass -passin pass:Aw2WLz9bHAideywh -out /working_dir/vendorkey.csr -config /config/csr.cnf
And tpm_private_key is generated using,
openssl rsa -provider-path /usr/lib64/ossl-packages/ -provider tpm2 -out tpm_privatekey.pem -in handle:0x81010002?pass -passin pass:Aw2WLz9bHAideywh
And tpm_public_key is generated using,
openssl rsa -provider-path /usr/lib64/ossl-packages/ -provider tpm2 -pubout -out tpm_publickey.pem -in handle:0x81010002?pass -passin pass:Aw2WLz9bHAideywh
And serialNo.pem is generated using,
We have serialNo.pem generated by using the vendorkey.csr from above and then CSR File is sent to the ca server to get it. And CA Server directly we cannot access it directly.
And rsa_private_key.pem,
openssl genrsa -out rsa-private.pem 2048
Attached the keys and pem files generated in the below link,
TPM_PEM_FILES.zip Link for files: https://github.com/tpm2-software/tpm2-openssl/files/13295681/TPM_PEM_FILES.zip
Prerequisite for sending IR using cmp:
- We have generated vendor key pair and stored in tpm, steps mentioned above.
- We have serialNo.pem generated by using the vendorkey.csr from above and then CSR File is sent to the ca server to get serialNo.pem and then stored in nv_index for later use.
- And we generated a rsa_private_key.pem which is used by application for connecting in TLS Mode.
- We are using OSSL_STORE apis to fetch the EVP_PKEY data later for setting the cmp_ctx
This is the password "Aw2WLz9bHAideywh" that is used in the code and also the command. Whatever the password you have mentioned earlier is incorrect password, that I'm aware because i haven't shared the exact password with you i just gave a reference on how we are generating the key pair in another machine. Now, I have shared with exact password on the machine I'm testing and also the key pair generation above.
cmp command: openssl cmp -provider-path /usr/lib64/ossl-packages/ -provider tpm2 -provider default -propquery '?provider=tpm2,tpm2.digest!=yes' -cmd ir -server 10.33.123.231:8081/pkix/ -recipient "/CN=CMPserver" -cert /working_dir/serialNo.pem -key handle:0x81010002?pass -keypass pass:Aw2WLz9bHAideywh -subject "/CN=Client" -certout test-my-cert.pem -cacertsout test-my-ca.pem
I tested with the command and IR is sent, but when tested through the code, it says missing Private key.
The code you sent looks good. I don't see anything wrong.
So, what can I conclude now? I'm not sure how to proceed. can you tell me how you tested it?
If you want to continue, you should write a single script that (assuming an empty TPM) will execute all the preparatory steps automatically with the correct passwords, etc. Not a text guide, a fully automated shell script (and the .c
file). Then we could both build the .c
file, run the script and see whether and how the results differ.
Hi, I'm Sharing the script files and cpp file in zip format.
tpm_script.sh will do the generation of keys and clear_tpm.sh will do the tpm_clear operations.
Ensure no tpm persistent handles are present. If present, clear them and run the tpm_script.sh
change the path in the tpm_script for storing the files.
Then generate private key using,
openssl genrsa -out rsa_private_key.pem 2048
Then execute the cpp file
g++ opensource_tpm.cpp -o opensource_tpm -lssl -lcrypto
After it is done, run clear_tpm.sh to remove the persistent handles to redo the operation again from generation of keys.
certificate is not shared because, it will be different in your machine and ca server is not directly accessible. Can you share the command on how you are generating the certificate in your machine for testing?
Hi @gotthardp ,
Can you help us here for the above issue? As you confirmed that the shared code is working in your machine. Can you explain what are we doing wrong or missing details in the code for performing IR?
These are the error logs in my machine.
807B57B2807F0000:error:020000B3:rsa routines:rsa_ossl_private_encrypt:missing private key:crypto/rsa/rsa_ossl.c:332: 807B57B2807F0000:error:1C880004:Provider routines:rsa_sign:RSA lib:providers/implementations/signature/rsa_sig.c:588: 807B57B2807F0000:error:06880006:asn1 encoding routines:ASN1_item_sign_ctx:EVP lib:crypto/asn1/a_sign.c:284: 807B57B2807F0000:error:1D00007F:CMP routines:ossl_cmp_msg_protect:error protecting message:crypto/cmp/cmp_protect.c:332: 807B57B2807F0000:error:1D0000A3:CMP routines:ossl_cmp_certreq_new:error creating certreq:crypto/cmp/cmp_msg.c:439:
Hi,
I have loaded the Private Key from TPM using openssl command,
openssl rsa -provider-path /usr/lib64/ossl-packages/ -provider tpm2 -out privatekey.pem -in handle:0x81010002
And the content of Private key is, -----BEGIN TSS2 PRIVATE KEY----- MIIBNQYGZ4EFCgEDoAMBAQECBEAAAAEEggEYARYAAQALAAYAcgAAABAAEAgAAAAA AAEA1ulSPzuYEDTez5D8VOczFDVMRliHQ748NB9KYSlKn0H7QPO3gpHOrzR6tNS8 mNki3MtoizWb8LU9fq5J98rLJzC1kzisF4tjYXqs+QcK7MU1HfeGxa+dwtY8d6jI Z2uew5i3u3nVPl/07tCwPXdv9FRjl5JoNPpADu7zmVMggwAEN6E+xw6PfouMWCwS 7R3p5IZFRZQn+lrX8xPPbcB7ImxfPjqx16PhknSng7PyQNMBkJNO0pA+20SxP4aP WkG0SwbLJM+9QJQ6x9dpyTIK0pl4XJyryuE7yvv/qxZqeL6eThLFhaOlfwYROdsH E2dsWX1sLdgNwVEy3sno6aR+CQQEAAIBgQ== -----END TSS2 PRIVATE KEY-----
But i want to convert to RSA based private key -----BEGIN PRIVATE KEY----- MIIBNQYGZ4EFCgEDoAMBAQECBEAAAAEEggEYARYAAQALAAYAcgAAABAAEAgAAAAA ............................
Is there any API to do the conversion for parsing the key into EVP_PKEY structure