tpm2-software / tpm2-tss-engine

OpenSSL Engine for TPM2 devices
https://tpm2-software.github.io
BSD 3-Clause "New" or "Revised" License
148 stars 97 forks source link

Tests rsasign_persistent and rsasign_persistent_emptyauth hang indefinitely with tpm2-tss 2.2.0 #79

Closed diabonas closed 5 years ago

diabonas commented 5 years ago

Building with tpm2-tss 2.2.0 causes the integration tests test/rsasign_persistent.sh and test/rsasign_persistent_emptyauth.sh to hang indefinitely while they are trying to execute

openssl pkeyutl -engine tpm2tss -keyform engine -inkey ${HANDLE} -sign -in ${DIR}/mydata.txt -out ${DIR}/mysig -passin stdin

The problem seems to be related to the tpm2-tss compatibility code in tpm2-tss-engine-common.c: if the #ifdef TSS22...#endif part is removed, everything works as expected.

diabonas commented 5 years ago

This seems to be related to the switch of the crypto backend to OpenSSL in tpm2-tss 2.2.0: if I compile tpm2-tss 2.2.0 with ./configure --with-crypto=gcrypt, everything works as expected. I guess this makes this a tpm2-tss bug rather than a tpm2-tss-engine issue. However I am currently unable to provide an example that reproduces the bug in tpm2-tss without the use of tpm2-tss-engine.

AndreasFuchsTPM commented 5 years ago

Could you post your openssl version ?

And could you run it with TSS2_LOG=esys+trace so we see on which function it hangs ?

diabonas commented 5 years ago

I am running OpenSSL 1.1.1a on Arch Linux. The call seems to get stuck at Esys_StartAuthSession:

+ openssl pkeyutl -engine tpm2tss -keyform engine -inkey 0x81000000 -sign -in /tmp/tmp.VZRre6DVfL/mydata.txt -out /tmp/tmp.VZRre6DVfL/mysig -passin stdin
engine "tpm2tss" set.
trace:esys:src/tss2-esys/api/Esys_ReadPublic.c:154:Esys_ReadPublic_Async() context=0x557318d50be0, objectHandle=418367 
trace:esys:src/tss2-esys/api/Esys_ReadPublic.c:253:Esys_ReadPublic_Finish() context=0x557318d50be0, outPublic=0x7fff8a0c3670, name=0x7fff8a0c3678,qualifiedName=0x7fff8a0c3680 
trace:esys:src/tss2-esys/esys_iutil.c:1284:iesys_check_response() No auths to verify 
trace:esys:src/tss2-esys/api/Esys_ReadPublic.c:154:Esys_ReadPublic_Async() context=0x557318d50be0, objectHandle=418367 
trace:esys:src/tss2-esys/api/Esys_ReadPublic.c:253:Esys_ReadPublic_Finish() context=0x557318d50be0, outPublic=0x7fff8a0c3720, name=(nil),qualifiedName=(nil) 
trace:esys:src/tss2-esys/esys_iutil.c:1284:iesys_check_response() No auths to verify 
trace:esys:src/tss2-esys/api/Esys_StartAuthSession.c:190:Esys_StartAuthSession_Async() context=0x557318d50be0, tpmKey=fff, bind=418367,nonceCaller=(nil), sessionType=00, symmetric=0x7fff8a0c371a,authHash=000b 
trace:esys:src/tss2-esys/esys_crypto.c:32:iesys_crypto_hash_get_digest_size() call: hashAlg=11 size=0x7fff8a0c3268 
trace:esys:src/tss2-esys/esys_crypto.c:57:iesys_crypto_hash_get_digest_size() return: *size=32 
Terminated
diabonas commented 5 years ago

The stack trace from the hanging OpenSSL process is interesting:

#0  0x00007f9540a67152 in read () from /usr/lib/libpthread.so.0
#1  0x00007f954076f771 in tcti_platform_command () from /usr/lib/libtss2-tcti-mssim.so.0
#2  0x00007f95407703de in Tss2_Tcti_Mssim_Init () from /usr/lib/libtss2-tcti-mssim.so.0
#3  0x00007f9540e04dbc in __tcti_get_ctx () from /home/jonas/tpm2-software/tpm2-tss-engine/.libs/libtpm2tss.so
#4  0x00007f9540e0509f in tcti_get_ctx () from /home/jonas/tpm2-software/tpm2-tss-engine/.libs/libtpm2tss.so
#5  0x00007f9540e03391 in esys_auxctx_init () from /home/jonas/tpm2-software/tpm2-tss-engine/.libs/libtpm2tss.so
#6  0x00007f9540e06598 in rand_bytes () from /home/jonas/tpm2-software/tpm2-tss-engine/.libs/libtpm2tss.so
#7  0x00007f954082de1b in iesys_cryptossl_random2b () from /usr/lib/libtss2-esys.so.0
#8  0x00007f954081cd8c in Esys_StartAuthSession_Async () from /usr/lib/libtss2-esys.so.0
#9  0x00007f954081d9da in Esys_StartAuthSession () from /usr/lib/libtss2-esys.so.0
#10 0x00007f9540e03a5c in tpm2tss_tpm2data_readtpm () from /home/jonas/tpm2-software/tpm2-tss-engine/.libs/libtpm2tss.so
#11 0x00007f9540e02c98 in loadkey () from /home/jonas/tpm2-software/tpm2-tss-engine/.libs/libtpm2tss.so
#12 0x00007f9540bccf91 in ENGINE_load_private_key () from /usr/lib/libcrypto.so.1.1
#13 0x00005583ce2cbf58 in ?? ()
#14 0x00005583ce2a1474 in ?? ()
#15 0x00005583ce29a005 in ?? ()
#16 0x00005583ce2833f0 in ?? ()
#17 0x00007f95408b6223 in __libc_start_main () from /usr/lib/libc.so.6
#18 0x00005583ce28346e in ?? ()

If I understand correctly, iesys_cryptossl_random2b from tpm2-tss calls RAND_bytes from OpenSSL. Because of the registered OpenSSL engine, it tries to get these random bytes from the TPM, and these interlacing calls to the TPM cause a block. Does that make any sense?

AndreasFuchsTPM commented 5 years ago

Good question... ESYS will use random bytes and cryptographic functions internally. I guess the choice of engine is up OpenSSL and application and not ESYS, right ?

Thus, this engine would have to set ENGINEs and METHODs to standard, whenever calling out to an external library ?

No idea, what best practice would be here...

@tstruk @dwmw2 Do you have any ideas ?

AndreasFuchsTPM commented 5 years ago

Funny enough, this is only a problem if we don't have a resource manager (e.g. using the simulator). In all other cases, the second tcti connection can actually be established.

Anyways, I'll consider this to be a problem of ESYS, because getting random bytes from the TPM for a salt that will secure following connections with the TPM does not make too much sense.

So please ignore my inquiry...