-
Notifications
You must be signed in to change notification settings - Fork 406
Description
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