The tcsd causes unnecessary authentication failures when a parent key (SRK)
with a password is used and a child key is supposed to be loaded into the
TPM. This patch avoids the failures by returning information about the
parent key to the caller rather than trying to load the key assuming the
parent key has no password (20 bytes of 0x0) and only returning information
about the parent key to the caller if the loading has failed. We use the
TCS_LOADKEY_INFO structure with all zeros as an indicator of a first call
and fill it out and return it to the client. On the client side we then
try to determine the password of the parent key and try another call with
either the parent key's password set or the parent key's password again
empty. This avoids one unnecessary authentication failure.

I noticed this issue when trying to develop an application that uses GnuTLS
tpmtool to create TPM keys and certtool for issuing certificates. I noticed
that with a hardware TPM I could only run my program once but could run it 5
times when using a vTPM. The vTPM seems to have a higher threshold for
engaging the lock out due to failed authentications than the hardware TPM does.
The program ran 5 times with the vTPM. My program itself does not cause
authentication failures but tcsd caused some, that this patch fixes, and
certtool itself causes some that would need to be 'somehow' fixed in certtool
itself. The improvement with this patch is so that the program now runs 5
times with a hardware TPM. After that the owner of the TPM has to issue the
TPM_ORD_ResetLockValue command.

The autentication failures are probably not so severe when the parent
key has no password. However, tpmtool (of GnuTLS) currently does not support
this and therefore we have to set an explicity password for the parent
key.

Signed-off-by: Stefan Berger <[email protected]>
---
 src/tcs/tcsi_ps.c  | 60 ++++++++++++++++++++++++++++++++++------------
 src/tspi/tspi_ps.c | 10 ++++++--
 2 files changed, 53 insertions(+), 17 deletions(-)

diff --git a/src/tcs/tcsi_ps.c b/src/tcs/tcsi_ps.c
index e7f6245..a0c9df4 100644
--- a/src/tcs/tcsi_ps.c
+++ b/src/tcs/tcsi_ps.c
@@ -494,6 +494,30 @@ TCS_GetRegisteredKeyBlob_Internal(TCS_CONTEXT_HANDLE 
hContext,     /* in */
        return TSS_SUCCESS;
 }
 
+static TSS_RESULT
+CopyKeyInfo_Internal(TCS_LOADKEY_INFO * pLoadKeyInfo,  /* in, out */
+                    TSS_UUID *parentUuid,              /* in */
+                    TSS_UUID *KeyUUID,                 /* in */
+                    UINT32 ordinal,                    /* in */
+                    UINT32 keySize,                    /* in */
+                    BYTE *keyBlob)                     /* in */
+{
+       BYTE blob[1000];
+       UINT64 offset = 0;
+
+       /* set up a load key info struct */
+       memcpy(&pLoadKeyInfo->parentKeyUUID, parentUuid, sizeof(TSS_UUID));
+       memcpy(&pLoadKeyInfo->keyUUID, KeyUUID, sizeof(TSS_UUID));
+
+       /* calculate the paramDigest */
+       LoadBlob_UINT32(&offset, ordinal, blob);
+       LoadBlob(&offset, keySize, blob, keyBlob);
+       if (Hash(TSS_HASH_SHA1, offset, blob,
+                (BYTE *)&pLoadKeyInfo->paramDigest.digest))
+               return TCSERR(TSS_E_INTERNAL_ERROR);
+       return 0;
+}
+
 TSS_RESULT
 TCSP_LoadKeyByUUID_Internal(TCS_CONTEXT_HANDLE hContext,       /* in */
                            TSS_UUID *KeyUUID,                  /* in */
@@ -508,6 +532,7 @@ TCSP_LoadKeyByUUID_Internal(TCS_CONTEXT_HANDLE hContext,    
/* in */
        UINT16 blobSize = sizeof(keyBlob);
        UINT64 offset;
        TCS_KEY_HANDLE parentTCSKeyHandle;
+       TCS_LOADKEY_INFO nullInfo;
 
        if (TPM_VERSION_IS(1,2))
                ordinal = TPM_ORD_LoadKey2;
@@ -572,27 +597,32 @@ TCSP_LoadKeyByUUID_Internal(TCS_CONTEXT_HANDLE hContext,  
/* in */
         * If no errors have happend up till now, then the parent is loaded and 
ready for use.
         * The parent's TCS Handle should be in parentTCSKeyHandle.
         ******************************************************/
+
+       memset(&nullInfo, 0, sizeof(nullInfo));
+
+       if (memcmp(&nullInfo, pLoadKeyInfo, sizeof(nullInfo)) == 0) {
+               /*********************************************************
+                * Do not fail by using the wrong auth on loading the key
+                * rather give the caller the key info and have him call
+                * again.
+                ********************************************************/
+               result = CopyKeyInfo_Internal(pLoadKeyInfo, &parentUuid, 
KeyUUID, ordinal,
+                                             keySize, keyBlob);
+               if (result)
+                       return result;
+               return TCSERR(TCS_E_KM_LOADFAILED);
+       }
+
        if ((result = LoadKeyByBlob_Internal(ordinal, hContext, 
parentTCSKeyHandle,
                                             keySize, keyBlob,
                                             NULL,
                                             phKeyTCSI, &keyslot))) {
                LogDebugFn("LoadKeyByBlob_Internal returned 0x%x", result);
                if (result == TCPA_E_AUTHFAIL && pLoadKeyInfo) {
-                       BYTE blob[1000];
-
-                       /* set up a load key info struct */
-                       memcpy(&pLoadKeyInfo->parentKeyUUID, &parentUuid, 
sizeof(TSS_UUID));
-                       memcpy(&pLoadKeyInfo->keyUUID, KeyUUID, 
sizeof(TSS_UUID));
-
-                       /* calculate the paramDigest */
-                       offset = 0;
-                       LoadBlob_UINT32(&offset, ordinal, blob);
-                       LoadBlob(&offset, keySize, blob, keyBlob);
-                       if (Hash(TSS_HASH_SHA1, offset, blob,
-                                (BYTE *)&pLoadKeyInfo->paramDigest.digest))
-                               result = TCSERR(TSS_E_INTERNAL_ERROR);
-
-                       result = TCSERR(TCS_E_KM_LOADFAILED);
+                       result = CopyKeyInfo_Internal(pLoadKeyInfo, 
&parentUuid, KeyUUID, ordinal,
+                                                     keySize, keyBlob);
+                       if (result == 0)
+                               result = TCSERR(TCS_E_KM_LOADFAILED);
                }
        }
 
diff --git a/src/tspi/tspi_ps.c b/src/tspi/tspi_ps.c
index 237fadf..797f8bb 100644
--- a/src/tspi/tspi_ps.c
+++ b/src/tspi/tspi_ps.c
@@ -74,8 +74,13 @@ Tspi_Context_LoadKeyByUUID(TSS_HCONTEXT tspContext,          
/* in */
                        if ((obj_rsakey_get_by_uuid(&info.parentKeyUUID, 
&keyHandle))) {
                                /* If that failed, look on disk, in User PS. */
                                if (ps_get_key_by_uuid(tspContext, 
&info.parentKeyUUID,
-                                                      &keyHandle))
-                                       return result;
+                                                      &keyHandle)) {
+                                       result = RPC_LoadKeyByUUID(tspContext, 
uuidData,
+                                                                  &info, 
&tcsKeyHandle);
+                                       if (result)
+                                               return result;
+                                       goto cont;
+                               }
                        }
 
                        if (obj_rsakey_get_policy(keyHandle, TSS_POLICY_USAGE,
@@ -92,6 +97,7 @@ Tspi_Context_LoadKeyByUUID(TSS_HCONTEXT tspContext,           
/* in */
                } else if (result)
                        return result;
 
+cont:
                /*check if provided UUID has an owner evict key UUID prefix */
                if (!memcmp(&uuidData, &owner_evict_uuid, sizeof(TSS_UUID)-1)) {
                        if ((result = obj_rsakey_add(tspContext, 
TSS_RSAKEY_FLAG_OWNEREVICT,
-- 
2.17.2



_______________________________________________
TrouSerS-tech mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/trousers-tech

Reply via email to