[Tpm2] Creating a Sealed RSA key for an Apache Server

Damiano Turriziani <[email protected]> Thu, 28 Sep 2023 16:09:08 +0200
Newsgroups dev.linux.lists.tpm2
Message-ID <CADRyO0iWmTBtnXa9RZVuieobBJrRE6hOU3wKb08xr3B4Fm-Ysw@mail.gmail.com>
Hi Folks,


I am a master degree student and my thesis is based on the usage of the
TPM2 and in particular implementing the Sealing operation using the ESYS
API library. My main goal is to protect an RSA private key with the Sealing
operation and try to use it with an Apache server.


I have tried two possible implementations:

   - the first one is based on creating the RSA key using the TPM and
   protecting it with the PCRs values but this implementation has some
   problems which I couldn’t solve and for this reason I tried the second
   solution;
   - The second one is based on creating the RSA key without the TPM and
   splitting it in chunks of 128 bytes in order to create multiple sealed
   objects that will be reassembled after the unsealing operation.


For the *first implementation* I made some changes to the *tpm2-openssl*
library in order to directly create an RSA key which depends on the PCRs
values.


The first problem I encountered  is that I had to manually check the status
of the PCRs when the Key was loaded by: creating a new Policy Session,
calling the *PolicyPCR* function (passing an empty *TPM2B_DIGEST*) and
retrieving the Policy Digest and comparing it with the one embedded in the
Key inPublic structure. I know from the documentation that all of these
steps could be avoided by calling the PolicyPCR function and passing it the
Policy Digest of the key so that it automatically checks if the Policy
Digest passed matches the current digest of the selected PCR but I wasn’t
able to reproduce this behaviour. Maybe I got the documentation wrong
because every time I try passing that value it returns:* Esys_PolicyPCR()
Esys Finish ErrorCode(0x000001c4) -> tpm:parameter(1):value is out of range
or is not correct for the context.*


The second problem instead was when I started the TLS Server using the* openssl
s_server -provider tpm2 -provider default -propquery ‘?provider=tpm2’
-accept 4431 -www -key myKey.pem -cert myCert.pem &* I could connect to it
only using* openssl s_client -provider tpm2 -provider default -propquery
‘?provider=tpm2’ -connect localhost:4431* even though in the test section
of tpm2-openssl the *curl* command is used. Same thing happens if
using *openssl
s_client *without the *-provider tpm2* parameters. In both cases it
returns: *error:02000088:rsa routines::salt length check failed. *


Instead, for the *second implementation* I created an RSA key, I splitted
it in chunks of 128 bytes and for each one of them I created a
sealed-object with the *Esys_Create* function. For each one of them I
retrieved the *outPublic* and the *outPrivate* data when they were created
and saved them in two different files. Because *outPublic* and *outPrivate*
have a fixed size I could retrieve them later when I wanted to unseal the
sealed-objects. So my idea is to make the Apache server accept in input
these two files in order to perform the unsealing and reassembling the RSA
private key.


I wanted to know if there was a better way to do that with respect to these
solutions, because the first one works only with few loopholes as
previously explained while the second solution theoretically works but I
haven’t modified the Apache source code to enable the unsealing of the
private key when the Apache Server starts.


Thanks,

Damiano Turriziani