tpm2-tss: Trying to load a primary key into a persistent hand in TPM, but get an error

Hi all, I encountered an error using the EAPI on Windows 10. My simple goal is to create a primary key and load it into TPM at a fixed location - 0x81000001 and then create a keypair under the primary and leave the handle in a folder.

Here is my setup for TPM using PowerShell (reference https://docs.microsoft.com/en-us/powershell/module/trustedplatformmodule/?view=windowsserver2022-ps):

Clear-Tpm

ConvertTo-TpmOwnerAuth -Passphrase "ownerauth"

Import-TpmOwnerAuth -OwnerAuthorization "5AtOuyKBA/UsW1xrqAwjxfSA1nM="

Initialize-Tpm

After this the PowerShelel shows TPM is ready:

PS C:\WINDOWS\system32> Get-Tpm

TpmPresent                : True
TpmReady                  : True
TpmEnabled                : True
TpmActivated              : True
TpmOwned                  : True
RestartPending            : False
ManufacturerId            : 1398033696
ManufacturerIdTxt         : STM
ManufacturerVersion       : 1.258.0.0
ManufacturerVersionFull20 : 1.258.0.0

ManagedAuthLevel          : Full
OwnerAuth                 : 5AtOuyKBA/UsW1xrqAwjxfSA1nM=
OwnerClearDisabled        : False
AutoProvisioning          : Enabled
LockedOut                 : False
LockoutHealTime           : 2 hours
LockoutCount              : 0
LockoutMax                : 32
SelfTest                  : {}

In my C code, it is simply trying to create a persistent primary

// I called initialization first
Esys_Initialize(&ectx, NULL, NULL);

// then, not sure if this is the right way to use it.
TPM2B_AUTH hieararchy_auth = { 0 };
Esys_TR_SetAuth(ectx, ESYS_TR_RH_OWNER, &hieararchy_auth );

// then create primary, this call did not fail
Esys_CreatePrimary(ectx, ESYS_TR_RH_OWNER, ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE, ..., &handle, ...);

// but this failed
Esys_EvictControl(ectx,
            ESYS_TR_RH_OWNER,
            handle,
            ESYS_TR_PASSWORD,
            ESYS_TR_NONE,
            ESYS_TR_NONE,
            0x81000001,
            &new_handle);

This is the error I got:

ERROR:esys:api\Esys_EvictControl.c:334:Esys_EvictControl_Finish() Received a non-TPM Error
ERROR:esys:api\Esys_EvictControl.c:114:Esys_EvictControl() Esys Finish ErrorCode (0x80280400)

Esys_EvictControl: 40:0x400:

I guess I’m confused when and how to pass the OWNER password "ownerauth". Any help is greatly appreciated! Thank you!

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 16 (7 by maintainers)

Most upvoted comments

The call below teaches ESYS, “hey, when you need the owner auth use this”.

Esys_TR_SetAuth(ectx, ESYS_TR_RH_OWNER, &hieararchy_auth );

But here you never set the password:

TPM2B_AUTH hieararchy_auth = { 0 };

The struct has a size and buffer field. You need to set buffer to the password and update the size field.

    const char password[] = "5AtOuyKBA/UsW1xrqAwjxfSA1nM=";
    TPM2B_AUTH hieararchy_auth = {
         .size = sizeof(password) - sizeof(char)
    };
    memcpy(hieararchy_auth.buffer, password, hieararchy_auth.size);

I usually roll that into a setpassword function since it gets used a lot, here is a sample:

static TSS2_RC set_password(ESYS_CONTEXT *ectx, ESYS_TR handle, const char *password)
{
    TPM2B_AUTH auth = { 0 };

    if (strlen(password) > sizeof(auth.buffer)) {
        // todo make better error
        return 1;
    }

    auth.size = strlen(password);
    memcpy(auth.buffer, password, auth.size);

    return Esys_TR_SetAuth(ectx, handle, &auth);
}

int main(int argc, char *argv[]) {

    ESYS_CONTEXT *ectx = NULL;
    Esys_Initialize(&ectx, NULL, NULL);
    return set_password(ectx, ESYS_TR_RH_OWNER, "5AtOuyKBA/UsW1xrqAwjxfSA1nM=");
}

Thank you so much @williamcroberts this saved my day! I was down in the robbit hole trying to explore Esys_StartAuthSession and Esys_TRSess_SetAttributes to somehow pass the password!