"Kevin O'Connor" <kevin@koconnor.net>
wrote on 01/06/2016 03:20:56 PM:
>
> On Wed, Jan 06, 2016 at 01:15:55PM -0500, Stefan Berger wrote:
> > From: Stefan Berger <stefanb@linux.vnet.ibm.com>
> >
> > Extend assert_physical_presence with checks for hardware physical
presence
> > support. If no hardware physical presence is asserted and the
SW assertion
> > is disable, -1 is returned.
> >
> > Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
> > ---
> > src/std/tcg.h | 2 ++
> > src/tcgbios.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++--
> > 2 files changed, 61 insertions(+), 2 deletions(-)
> >
> > diff --git a/src/std/tcg.h b/src/std/tcg.h
> > index 9f7f021..00be533 100644
> > --- a/src/std/tcg.h
> > +++ b/src/std/tcg.h
> > @@ -70,6 +70,7 @@
> >
> > /* TPM command error codes */
> > #define TPM_INVALID_POSTINIT
0x26
> > +#define TPM_BAD_PRESENCE
0x2d
> > #define TPM_BAD_LOCALITY
0x3d
> >
> > /* TPM command tags */
> > @@ -285,6 +286,7 @@ enum permFlagsIndex {
> > PERM_FLAG_IDX_ALLOW_MAINTENANCE,
> > PERM_FLAG_IDX_PHYSICAL_PRESENCE_LIFETIME_LOCK,
> > PERM_FLAG_IDX_PHYSICAL_PRESENCE_HW_ENABLE,
> > + PERM_FLAG_IDX_PHYSICAL_PRESENCE_CMD_ENABLE,
> > };
> >
> >
> > diff --git a/src/tcgbios.c b/src/tcgbios.c
> > index d6a8495..6a6b6b0 100644
> > --- a/src/tcgbios.c
> > +++ b/src/tcgbios.c
> > @@ -446,7 +446,7 @@ err_exit:
> > return -1;
> > }
> >
> > -static u32
> > +static int
> > read_stclear_flags(char *buf, int buf_len)
> > {
> > memset(buf, 0, buf_len);
> > @@ -480,7 +480,32 @@ read_permanent_flags(char *buf, int buf_len)
> > return 0;
> > }
> >
> > -static u32
> > +static int
> > +has_hw_physical_presence(struct tpm_permanent_flags *pf, int
*has_hw_pp)
> > +{
> > + u32 ordinal;
> > +
> > + /* We cannot read hardware physical presence from
a flag;
> > + * it has to be inferred from the error code to
a command that
> > + * needs physical presence
> > + */
> > + if (pf->flags[PERM_FLAG_IDX_DISABLE])
> > + ordinal = TPM_ORD_PhysicalDisable;
> > + else
> > + ordinal = TPM_ORD_PhysicalEnable;
> > +
> > + int ret = tpm_send_cmd(0, ordinal, NULL, 0, TPM_DURATION_TYPE_SHORT);
>
> I'm leery of code that automatically issues a command that nominally
> alters non-volatile memory as I fear it could cause the hardware to
> wear out. So, I'd avoid doing this unless the above is definitely
not
> an issue.
It's implementation-dependent what the TPM will do
once a permanent flag is set to the
same value it already is. It may write it back into
NVRAM or not.
>
> If you want the menu to also be usable on machines with hardware
> physical presence, then I'm fine with enabling the menu after just
> checking that HW_ENABLE is true.
In this case we may encounter errors if hardware physical
presence is not actually set.
>
> [...]
> > +static int
> > assert_physical_presence(int verbose)
> > {
> > struct tpm_stclear_flags stcf;
> > @@ -492,6 +517,38 @@ assert_physical_presence(int verbose)
> > /* physical presence already
asserted */
> > return 0;
>
> I don't think we need to read stclear flags here - I think it would
be
> simpler to just issue PhysicalPresence_PRESENT. If it succeeds
then
> we've successfully asserted physical presence, and if it fails then
go
> on to read permanent flags.
Ok.
>
> > + struct tpm_permanent_flags pf;
> > + ret = read_permanent_flags((char *)&pf, sizeof(pf));
> > + if (ret)
> > + return -1;
> > +
> > + /* check if hardware physical presence is supported
and asserted */
> > + if (pf.flags[PERM_FLAG_IDX_PHYSICAL_PRESENCE_HW_ENABLE])
{
> > + int has_hw_pp;
> > + ret = has_hw_physical_presence(&pf,
&has_hw_pp);
> > + if (verbose && !has_hw_pp)
> > + printf("Hardware
physical presence is not asserted.\n\n");
> > + if (ret)
> > + return ret;
> > +
> > + if (has_hw_pp)
> > + return 0;
> > +
> > + if (!pf.flags[PERM_FLAG_IDX_PHYSICAL_PRESENCE_CMD_ENABLE])
{
> > + /* cannot enable phys.
presence using command */
> > + if (verbose)
> > + printf("Error:
Physical presence SW assertion is
> disabled.\n\n");
> > + return -1;
> > + }
> > + }
> > +
> > + if (stcf.flags[STCLEAR_FLAG_IDX_PHYSICAL_PRESENCE_LOCK])
{
> > + /* physical presence cannot be changed
anymore */
> > + if (verbose)
> > + printf("Error:
Physical presence assertion is locked.\n\n");
> > + return -1;
> > + }
> > +
> > ret = tpm_send_check_cmd(0, TPM_ORD_PhysicalPresence,
> >
PhysicalPresence_CMD_ENABLE,
> >
sizeof(PhysicalPresence_CMD_ENABLE),
>
> This seems to issue CMD_ENABLE even if CMD_ENABLE may have already
> been on - I'm leery of that.
I'll remove that.
>
> To summarize, what about this sequence during startup:
>
> PhysicalPresence_PRESENT
> if fail:
> flags = read_permanent_flags()
> if flags.HW_ENABLE:
> return success
> if !flags.CMD_ENABLE && !flags.LOCK:
> PhysicalPresence_CMD_ENABLE
> PhysicalPresence_PRESENT
>
> Then we don't have to issue PRESENT or CMD_ENABLE anywhere else in
the
> code.
Ok.
Stefan