Skip to content

tpm2_unseal fails when both --pwd-session and -p pcr:sha256:<pcrs> are used #3521

@matthewruffell

Description

@matthewruffell

Hi @JuergenReppSIT

I found a minor issue in tpm2_unseal with --pwd-session and -p pcr:sha256: when using both at the same time, for use on FIPS systems, but is also reproduces on normal non-FIPS systems.

On current master branch, works on normal non-FIPS systems:

Reproducer:

$ sudo apt install clevis clevis-tpm2 clevis-initramfs clevis-luks
$ mkfs.ext4 /dev/vdc
$ cryptsetup luksFormat --type luks2 /dev/vdc
$ sudo clevis luks bind -d /dev/vdc tpm2 '{"hash":"sha256","pcr_bank":"sha256","key":"rsa","pcr_ids":"0,2,4,7"}}'
$ clevis luks unlock -d /dev/vdc
...
+ pcr_ids=0,2,4,7
+ pcr_spec=
+ '[' -n 0,2,4,7 ']'
++ jose fmt -j- -Og clevis -g tpm2 -g pcr_bank -Su-
+ pcr_bank=sha256
+ pcr_spec=sha256:0,2,4,7
+ jose b64 dec -i- -O /tmp/tmp.WfP6ZPfRwk/jwk.pub
+ jose b64 dec -i- -O /tmp/tmp.WfP6ZPfRwk/jwk.priv
+ case "$TPM2TOOLS_VERSION" in
+ tpm2_createprimary --pwd-session -Q -C o -g sha256 -G rsa -c /tmp/tmp.WfP6ZPfRwk/primary.context
+ '[' -n '' ']'
+ case "$TPM2TOOLS_VERSION" in
+ tpm2_load --pwd-session -Q -C /tmp/tmp.WfP6ZPfRwk/primary.context -u /tmp/tmp.WfP6ZPfRwk/jwk.pub -r /tmp/tmp.WfP6ZPfRwk/jwk.priv -c /tmp/tmp.WfP6ZPfRwk/load.context
+ '[' -n '' ']'
+ case "$TPM2TOOLS_VERSION" in
++ tpm2_unseal --pwd-session -c /tmp/tmp.WfP6ZPfRwk/load.context -p pcr:sha256:0,2,4,7
ERROR: Cannot specify password type "pcr:"
ERROR: Invalid item handle authorization
ERROR: Unable to run tpm2_unseal
+ jwk=
+ fail=1
+ '[' -n 1 ']'
+ echo 'Unsealing jwk from TPM failed!'
Unsealing jwk from TPM failed!
+ exit 1
...

Note that I added --pwd-session to the tpm2 tools commands in the clevis script located at /usr/bin/clevis-decrypt-tpm2.

On a standard non-FIPS system, if we turn off --pwd-session and use the 0
length HMAC auth:

# tpm2_unseal -c /tmp/tmp.WfP6ZPfRwk/load.context -p pcr:sha256:0,2,4,7
{"alg":"A256GCM","k":"lTdx7D-xCtHNGAqgWwZC_R8QHqOQ6LxQRyuB1aRPfpQ","key_ops":["encrypt","decrypt"],"kty":"oct"}

it works.

On a FIPS system though:

# tpm2_unseal -c /tmp/tmp.VtpWqjSPnb/load.context -p pcr:sha256:0,2,4,7
ERROR:esys_crypto:src/tss2-esys/esys_crypto_ossl.c:412:iesys_cryptossl_hmac_start() ErrorCode (0x00070001) DigestSignInit 
ERROR:esys_crypto:src/tss2-esys/esys_crypto.c:185:iesys_crypto_authHmac() Error ErrorCode (0x00070001) 
ERROR:esys:src/tss2-esys/esys_iutil.c:1244:iesys_compute_hmac() HMAC error ErrorCode (0x00070001) 
ERROR:esys:src/tss2-esys/esys_iutil.c:1354:iesys_gen_auths() Error while computing hmacs ErrorCode (0x00070001) 
ERROR:esys:src/tss2-esys/api/Esys_Unseal.c:186:Esys_Unseal_Async() Error in computation of auth values ErrorCode (0x00070001) 
ERROR:esys:src/tss2-esys/api/Esys_Unseal.c:75:Esys_Unseal() Error in async function ErrorCode (0x00070001) 
ERROR: Esys_Unseal(0x70001) - esapi:Catch all for all errors not otherwise specified
ERROR: Unable to run tpm2_unseal

So we still need --pwd-session.

# tpm2_unseal --pwd-session -c /tmp/tmp.VtpWqjSPnb/load.context -p pcr:sha256:0,2,4,7
ERROR: Cannot specify password type "pcr:"
ERROR: Invalid item handle authorization
ERROR: Unable to run tpm2_unseal

I was looking at lib/tpm2_auth_util.c at:

...
tool_rc tpm2_auth_util_from_optarg(ESYS_CONTEXT *ectx, const char *password,
        tpm2_session **session, bool is_restricted) {
...
    /* starts with pcr: */
    bool is_pcr = !strncmp(password, PCR_PREFIX, PCR_PREFIX_LEN);
    if (is_pcr) {
        if (is_restricted) {
            LOG_ERR("Cannot specify password type \"pcr:\"");
            return tool_rc_general_error;
        }
        return handle_pcr(ectx, password, session);
    }

    /* must be a password */
    if (is_restricted) {
        /* ESYS_TR_PASSWORD will be used as handle. */
        return handle_password_session(NULL, password, session);
    } else {
        /* A hmac session will be created. */
        return handle_password_session(ectx, password, session);
    }
...

I did a couple quick tests, one where I put the /* must be a password */ block before the /* starts with pcr: */ block, and also a test with a change to the flow for if(is_pcr) then if(is_restricted) to say:

    /* starts with pcr: */
    bool is_pcr = !strncmp(password, PCR_PREFIX, PCR_PREFIX_LEN);
    if (is_pcr) {
        if (is_restricted) {
            return handle_password_session(NULL, password, session);
        }
        return handle_pcr(ectx, password, session);
    }

both result in:

# tpm2_unseal --pwd-session -c /tmp/tmp.VtpWqjSPnb/load.context -p pcr:sha256:0,2,4,7
WARNING:esys:src/tss2-esys/api/Esys_Unseal.c:295:Esys_Unseal_Finish() Received TPM Error 
ERROR:esys:src/tss2-esys/api/Esys_Unseal.c:98:Esys_Unseal() Esys Finish ErrorCode (0x0000012f) 
ERROR: Esys_Unseal(0x12F) - tpm:error(2.0): authValue or authPolicy is not available for selected entity
ERROR: Unable to run tpm2_unseal

So I suppose we need to be a bit more clever about the use of ESYS_TR_PASSWORD
for one part of the authentication, and then pcr:sha256:0,2,4,7 for the other
part.

Context:
Issue: tpm2-software/tpm2-tss#2889
Patch that introduces --pwd-session: 00c1c2b

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions