RPM Package Manager, CVS Repository
  http://rpm5.org/cvs/
  ____________________________________________________________________________

  Server: rpm5.org                         Name:   Jeff Johnson
  Root:   /v/rpm/cvs                       Email:  [email protected]
  Module: rpm                              Date:   25-Jul-2010 17:00:39
  Branch: HEAD                             Handle: 2010072515003800

  Modified files:
    rpm/rpmio               rpmtpm.c ttpm.c

  Log:
    - tpm: WIP.

  Summary:
    Revision    Changes     Path
    1.3         +32 -29     rpm/rpmio/rpmtpm.c
    2.2         +1019 -14   rpm/rpmio/ttpm.c
  ____________________________________________________________________________

  patch -p0 <<'@@ .'
  Index: rpm/rpmio/rpmtpm.c
  ============================================================================
  $ cvs diff -u -r1.2 -r1.3 rpmtpm.c
  --- rpm/rpmio/rpmtpm.c        24 Jul 2010 18:05:50 -0000      1.2
  +++ rpm/rpmio/rpmtpm.c        25 Jul 2010 15:00:38 -0000      1.3
  @@ -39,6 +39,38 @@
       return rc;
   }
   
  +/*==============================================================*/
  +
  +static int rpmtpmGetPhysicalCMDEnable(rpmtpm tpm)
  +{
  +    int xx;
  +    STACK_TPM_BUFFER( subcap );
  +    STACK_TPM_BUFFER( resp );
  +    STACK_TPM_BUFFER( tb );
  +    TPM_PERMANENT_FLAGS permanentFlags;
  +
  +    STORE32(subcap.buffer, 0, TPM_CAP_FLAG_PERMANENT);
  +
  +    subcap.used = 4;
  +    xx = rpmtpmErr(tpm, "GetCapability",
  +     TPM_GetCapability(TPM_CAP_FLAG, &subcap, &resp));
  +    if (xx)
  +     goto exit;
  +
  +    TSS_SetTPMBuffer(&tb, resp.buffer, resp.used);
  +
  +    xx = rpmtpmErr(tpm, "ReadPermanentFlags",
  +     TPM_ReadPermanentFlags(&tb, 0, &permanentFlags, resp.used));
  +    if (xx)
  +     goto exit;
  +
  +    tpm->enabled = permanentFlags.physicalPresenceCMDEnable;
  +
  +exit:
  +    return xx;
  +}
  +
  +/*==============================================================*/
   
   /*...@-mustmod@*/    /* XXX splint on crack */
   static void rpmtpmFini(void * _tpm)
  @@ -72,35 +104,6 @@
       return tpm;
   }
   
  -static int rpmtpmGetPhysicalCMDEnable(rpmtpm tpm)
  -{
  -    int xx;
  -    STACK_TPM_BUFFER( subcap );
  -    STACK_TPM_BUFFER( resp );
  -    STACK_TPM_BUFFER( tb );
  -    TPM_PERMANENT_FLAGS permanentFlags;
  -
  -    STORE32(subcap.buffer, 0, TPM_CAP_FLAG_PERMANENT);
  -
  -    subcap.used = 4;
  -    xx = rpmtpmErr(tpm, "GetCapability",
  -     TPM_GetCapability(TPM_CAP_FLAG, &subcap, &resp));
  -    if (xx)
  -     goto exit;
  -
  -    TSS_SetTPMBuffer(&tb, resp.buffer, resp.used);
  -
  -    xx = rpmtpmErr(tpm, "ReadPermanentFlags",
  -     TPM_ReadPermanentFlags(&tb, 0, &permanentFlags, resp.used));
  -    if (xx)
  -     goto exit;
  -
  -    tpm->enabled = permanentFlags.physicalPresenceCMDEnable;
  -
  -exit:
  -    return xx;
  -}
  -
   rpmtpm rpmtpmNew(const char * fn, int flags)
   {
       rpmtpm tpm = rpmtpmGetPool(_rpmtpmPool);
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/rpmio/ttpm.c
  ============================================================================
  $ cvs diff -u -r2.1 -r2.2 ttpm.c
  --- rpm/rpmio/ttpm.c  24 Jul 2010 18:05:50 -0000      2.1
  +++ rpm/rpmio/ttpm.c  25 Jul 2010 15:00:38 -0000      2.2
  @@ -1,10 +1,54 @@
  +/*
  + * (c) Copyright IBM Corporation 2006, 2010.
  + *
  + * All rights reserved.
  + *
  + * Redistribution and use in source and binary forms, with or without
  + * modification, are permitted provided that the following conditions are
  + * met:
  + *
  + * Redistributions of source code must retain the above copyright notice,
  + * this list of conditions and the following disclaimer.
  + *
  + * Redistributions in binary form must reproduce the above copyright
  + * notice, this list of conditions and the following disclaimer in the
  + * documentation and/or other materials provided with the distribution.
  + *
  + * Neither the names of the IBM Corporation nor the names of its
  + * contributors may be used to endorse or promote products derived from
  + * this software without specific prior written permission.
  + *
  + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  + */
  +
   #include "system.h"
   
   #include <rpmio.h>
  +#include <rpmtpm.h>
   #include <poptIO.h>
   
  -#define      _RPMTPM_INTERNAL
  -#include <rpmtpm.h>
  +#define TPM_POSIX            1       /* XXX FIXME: move to tpm-sw */
  +#define TPM_V12                      1
  +#define TPM_NV_DISK          1
  +#define TPM_MAXIMUM_KEY_SIZE 4096
  +#define TPM_AES                      1
  +
  +#include <tpm.h>
  +#include <tpmutil.h>
  +#include <tpmfunc.h>
  +
  +#include <openssl/pem.h>
  +#include <openssl/rsa.h>
   
   #include "debug.h"
   
  @@ -19,34 +63,995 @@
   extern int _pgp_print;
   /*...@=redecl@*/
   
  -static int use_fips;
  -static int selftest_only;
  +static
  +int rpmtpmErr(rpmtpm tpm, const char * msg, uint32_t mask, uint32_t rc)
  +        /*...@*/
  +{
  +    uint32_t err = rc & (mask ? mask : 0xffffffff);
  +    if (err || _rpmtpm_debug)
  +        fprintf (stderr, "*** TPM_%s rc %u: %s\n", msg, rc,
  +             (err ? TPM_GetErrMsg(rc) : "Success"));
  +    return rc;
  +}
  +
  +/*==============================================================*/
  +
  +/*...@-redef@*/
  +typedef struct key_s {
  +    uint32_t    v;
  +/*...@observer@*/
  +    const char *n;
  +} KEY;
  +/*...@=redef@*/
  +
  +/*...@observer@*/
  +static const char * tblName(uint32_t v, KEY * tbl, size_t ntbl)
  +     /*...@*/
  +{
  +    const char * n = NULL;
  +    static char buf[256];
  +    size_t i;
  +
  +    for (i = 0; i < ntbl; i++) {
  +     if (v != tbl[i].v)
  +         continue;
  +     n = tbl[i].n;
  +     break;
  +    }
  +    if (n == NULL) {
  +     (void) snprintf(buf, sizeof(buf), "0x%x", (unsigned)v);
  +     n = buf;
  +    }
  +    return n;
  +}
  +
  +#define _ENTRY(_v)      { TPM_ORD_##_v, #_v, }
  +static KEY TPM_ORD[] = {
  +    _ENTRY(ActivateIdentity),
  +    _ENTRY(AuthorizeMigrationKey),
  +    _ENTRY(CertifyKey),
  +    _ENTRY(CertifyKey2),
  +    _ENTRY(CertifySelfTest),
  +    _ENTRY(ChangeAuth),
  +    _ENTRY(ChangeAuthAsymFinish),
  +    _ENTRY(ChangeAuthAsymStart),
  +    _ENTRY(ChangeAuthOwner),
  +    _ENTRY(CMK_ApproveMA),
  +    _ENTRY(CMK_ConvertMigration),
  +    _ENTRY(CMK_CreateBlob),
  +    _ENTRY(CMK_CreateKey),
  +    _ENTRY(CMK_CreateTicket),
  +    _ENTRY(CMK_SetRestrictions),
  +    _ENTRY(ContinueSelfTest),
  +    _ENTRY(ConvertMigrationBlob),
  +    _ENTRY(CreateCounter),
  +    _ENTRY(CreateEndorsementKeyPair),
  +    _ENTRY(CreateMaintenanceArchive),
  +    _ENTRY(CreateMigrationBlob),
  +    _ENTRY(CreateRevocableEK),
  +    _ENTRY(CreateWrapKey),
  +    _ENTRY(DAA_Join),
  +    _ENTRY(DAA_Sign),
  +    _ENTRY(Delegate_CreateKeyDelegation),
  +    _ENTRY(Delegate_CreateOwnerDelegation),
  +    _ENTRY(Delegate_LoadOwnerDelegation),
  +    _ENTRY(Delegate_Manage),
  +    _ENTRY(Delegate_ReadTable),
  +    _ENTRY(Delegate_UpdateVerification),
  +    _ENTRY(Delegate_VerifyDelegation),
  +    _ENTRY(DirRead),
  +    _ENTRY(DirWriteAuth),
  +    _ENTRY(DisableForceClear),
  +    _ENTRY(DisableOwnerClear),
  +    _ENTRY(DisablePubekRead),
  +    _ENTRY(DSAP),
  +    _ENTRY(EstablishTransport),
  +    _ENTRY(EvictKey),
  +    _ENTRY(ExecuteTransport),
  +    _ENTRY(Extend),
  +    _ENTRY(FieldUpgrade),
  +    _ENTRY(FlushSpecific),
  +    _ENTRY(ForceClear),
  +    _ENTRY(GetAuditDigest),
  +    _ENTRY(GetAuditDigestSigned),
  +    _ENTRY(GetAuditEvent),
  +    _ENTRY(GetAuditEventSigned),
  +    _ENTRY(GetCapability),
  +    _ENTRY(GetCapabilityOwner),
  +    _ENTRY(GetCapabilitySigned),
  +    _ENTRY(GetOrdinalAuditStatus),
  +    _ENTRY(GetPubKey),
  +    _ENTRY(GetRandom),
  +    _ENTRY(GetTestResult),
  +    _ENTRY(GetTicks),
  +    _ENTRY(IncrementCounter),
  +    _ENTRY(Init),
  +    _ENTRY(KeyControlOwner),
  +    _ENTRY(KillMaintenanceFeature),
  +    _ENTRY(LoadAuthContext),
  +    _ENTRY(LoadContext),
  +    _ENTRY(LoadKey),
  +    _ENTRY(LoadKey2),
  +    _ENTRY(LoadKeyContext),
  +    _ENTRY(LoadMaintenanceArchive),
  +    _ENTRY(LoadManuMaintPub),
  +    _ENTRY(MakeIdentity),
  +    _ENTRY(MigrateKey),
  +    _ENTRY(NV_DefineSpace),
  +    _ENTRY(NV_ReadValue),
  +    _ENTRY(NV_ReadValueAuth),
  +    _ENTRY(NV_WriteValue),
  +    _ENTRY(NV_WriteValueAuth),
  +    _ENTRY(OIAP),
  +    _ENTRY(OSAP),
  +    _ENTRY(OwnerClear),
  +    _ENTRY(OwnerReadInternalPub),
  +    _ENTRY(OwnerReadPubek),
  +    _ENTRY(OwnerSetDisable),
  +    _ENTRY(PCR_Reset),
  +    _ENTRY(PcrRead),
  +    _ENTRY(PhysicalDisable),
  +    _ENTRY(PhysicalEnable),
  +    _ENTRY(PhysicalSetDeactivated),
  +    _ENTRY(Quote),
  +    _ENTRY(Quote2),
  +    _ENTRY(ReadCounter),
  +    _ENTRY(ReadManuMaintPub),
  +    _ENTRY(ReadPubek),
  +    _ENTRY(ReleaseCounter),
  +    _ENTRY(ReleaseCounterOwner),
  +    _ENTRY(ReleaseTransportSigned),
  +    _ENTRY(Reset),
  +    _ENTRY(ResetLockValue),
  +    _ENTRY(RevokeTrust),
  +    _ENTRY(SaveAuthContext),
  +    _ENTRY(SaveContext),
  +    _ENTRY(SaveKeyContext),
  +    _ENTRY(SaveState),
  +    _ENTRY(Seal),
  +    _ENTRY(Sealx),
  +    _ENTRY(SelfTestFull),
  +    _ENTRY(SetCapability),
  +    _ENTRY(SetOperatorAuth),
  +    _ENTRY(SetOrdinalAuditStatus),
  +    _ENTRY(SetOwnerInstall),
  +    _ENTRY(SetOwnerPointer),
  +    _ENTRY(SetRedirection),
  +    _ENTRY(SetTempDeactivated),
  +    _ENTRY(SHA1Complete),
  +    _ENTRY(SHA1CompleteExtend),
  +    _ENTRY(SHA1Start),
  +    _ENTRY(SHA1Update),
  +    _ENTRY(Sign),
  +    _ENTRY(Startup),
  +    _ENTRY(StirRandom),
  +    _ENTRY(TakeOwnership),
  +    _ENTRY(Terminate_Handle),
  +    _ENTRY(TickStampBlob),
  +    _ENTRY(UnBind),
  +    _ENTRY(Unseal),
  +};
  +static size_t nTPM_ORD = sizeof(TPM_ORD) / sizeof(TPM_ORD[0]);
  +#undef       _ENTRY
  +
  +#define _ENTRY(_v)      { TPM_CAP_##_v, #_v, }
  +static KEY TPM_CAP[] = {
  +    _ENTRY(ORD),             /* Boolean. TRUE indicates the TPM supports
  +                                   the ordinal. FALSE indicates the TPM does 
not
  +                                   support the ordinal. Unimplemented 
optional
  +                                   ordinals and unused (unassigned) ordinals
  +                                   return FALSE. */
  +    _ENTRY(ALG),             /* Boolean. TRUE means that the TPM supports
  +                                   the asymmetric algorithm for TPM_Sign,
  +                                   TPM_Seal, TPM_UnSeal and TPM_UnBind and
  +                                   related commands. FALSE indicates that the
  +                                   asymmetric algorithm is not supported.
  +                                   The TPM MAY return TRUE or FALSE for other
  +                                   than asymmetric algorithms that it 
supports.
  +                                   Unassigned and unsupported algorithm IDs
  +                                   return FALSE.*/
  +    _ENTRY(PID),             /* Boolean. TRUE indicates the TPM supports
  +                                   the protocol, FALSE indicates the TPM
  +                                   does not support the protocol.  */
  +    _ENTRY(FLAG),            /* Return the TPM_PERMANENT_FLAGS or the
  +                                              TPM_STCLEAR_FLAGS structure */
  +    _ENTRY(PROPERTY),                /* See following table for the subcaps 
*/
  +    _ENTRY(VERSION),         /* TPM_STRUCT_VER. The Major and Minor must
  +                                   indicate 1.1. The firmware revision MUST
  +                                   indicate 0.0 */
  +    _ENTRY(KEY_HANDLE),              /* TPM_KEY_HANDLE_LIST. Enumerates all
  +                                   key handles loaded on the TPM.  */
  +    _ENTRY(CHECK_LOADED),    /* Boolean. TRUE indicates the TPM has
  +                                   enough memory available to load a key of
  +                                   the type specified by TPM_KEY_PARMS.
  +                                   FALSE indicates that the TPM does not have
  +                                   enough memory.  */
  +    _ENTRY(SYM_MODE),                /* Subcap TPM_SYM_MODE
  +                                   Boolean. TRUE indicates that the TPM
  +                                   supports the TPM_SYM_MODE, FALSE indicates
  +                                   the TPM does not support the mode. */
  +    _ENTRY(KEY_STATUS),              /* Boolean value of ownerEvict. The 
handle
  +                                   MUST point to a valid key handle.*/
  +    _ENTRY(NV_LIST),         /* A list of TPM_NV_INDEX values that are
  +                                   currently allocated NV storage through
  +                                   TPM_NV_DefineSpace. */
  +    _ENTRY(MFR),             /* Manufacturer specific. The manufacturer may
  +                                   provide any additional information 
regarding
  +                                   the TPM and the TPM state but MUST not 
expose
  +                                   any sensitive information.  */
  +    _ENTRY(NV_INDEX),                /* TPM_NV_DATA_PUBLIC. Indicates the
  +                                   values for the TPM_NV_INDEX. Returns
  +                                   TPM_BADINDEX if index is not in the
  +                                   TPM_CAP_NV_LIST list. */
  +    _ENTRY(TRANS_ALG),               /* Boolean. TRUE means the TPM supports
  +                                   the algorithm for TPM_EstablishTransport,
  +                                   TPM_ExecuteTransport and
  +                                   TPM_ReleaseTransportSigned. FALSE 
indicates
  +                                   the algorithm is not supported."
  +                                              */
  +    _ENTRY(HANDLE),          /* TPM_KEY_HANDLE_LIST. Enumerates all handles
  +                                   currently loaded in the TPM for the given
  +                                   resource type.  */
  +    _ENTRY(TRANS_ES),                /* Boolean. TRUE means the TPM supports
  +                                   the encryption scheme in a transport 
session
  +                                   for at least one algorithm..  */
  +    _ENTRY(AUTH_ENCRYPT),    /* Boolean. TRUE indicates that the TPM
  +                                   supports the encryption algorithm in OSAP
  +                                   encryption of AuthData values */
  +    _ENTRY(SELECT_SIZE),     /* Boolean. TRUE indicates that the TPM
  +                                   supports the size for the given version.
  +                                   For instance a request could ask for 
version
  +                                   1.1 size 2 and the TPM would indicate 
TRUE.
  +                                   For 1.1 size 3 the TPM would indicate 
FALSE.
  +                                   For 1.2 size 3 the TPM would indicate 
TRUE. */
  +    _ENTRY(DA_LOGIC),                /* (OPTIONAL)
  +                                   TPM_DA_INFO or TPM_DA_INFO_LIMITED.
  +                                   returns data for the selected entity type
  +                                   e.g.,
  +                                       TPM_ET_KEYHANDLE,
  +                                       TPM_ET_OWNER,
  +                                       TPM_ET_SRK,
  +                                       TPM_ET_COUNTER,
  +                                       TPM_ET_OPERATOR, etc.).
  +                                   If the implemented dictionary attack logic
  +                                   does not support different secret types,
  +                                   the entity type can be ignored. */
  +    _ENTRY(VERSION_VAL),     /* TPM_CAP_VERSION_INFO. The TPM fills in the
  +                                   structure and returns the information
  +                                   indicating what the TPM supports. */
  +    _ENTRY(FLAG_PERMANENT),  /* Return the TPM_PERMANENT_FLAGS structure */
  +    _ENTRY(FLAG_VOLATILE)    /* Return the TPM_STCLEAR_FLAGS structure */
  +};
  +static size_t nTPM_CAP = sizeof(TPM_CAP) / sizeof(TPM_CAP[0]);
  +#undef       _ENTRY
  +
  +#define _ENTRY(_v)      { TPM_CAP_PROP_##_v, #_v, }
  +static KEY TPM_CAP_PROP[] = {
  +    _ENTRY(PCR),             /* uint32_t. Returns the number of PCR
  +                                   registers supported by the TPM */
  +    _ENTRY(DIR),             /* uint32_t. Deprecated. Returns the number of
  +                                   DIR, which is now fixed at 1 */
  +    _ENTRY(MANUFACTURER),    /* uint32_t.  Returns the vendor ID
  +                                   unique to each TPM manufacturer. */
  +    _ENTRY(KEYS),            /* uint32_t. Returns the number of 2048-
  +                                   bit RSA keys that can be loaded. This may
  +                                   vary with time and circumstances. */
  +    _ENTRY(MIN_COUNTER),     /* uint32_t. The minimum amount of time in
  +                                   10ths of a second that must pass between
  +                                   invocations of incrementing the monotonic
  +                                   counter. */
  +    _ENTRY(AUTHSESS),                /* uint32_t. The number of available
  +                                   authorization sessions. This may vary with
  +                                   time and circumstances. */
  +    _ENTRY(TRANSESS),                /* uint32_t. The number of available 
transport
  +                                   sessions. This may vary with time and
  +                                   circumstances.  */
  +    _ENTRY(COUNTERS),                /* uint32_t. The number of available 
monotonic
  +                                   counters. This may vary with time and
  +                                   circumstances. */
  +    _ENTRY(MAX_AUTHSESS),    /* uint32_t. The maximum number of loaded
  +                                   authorization sessions the TPM supports */
  +    _ENTRY(MAX_TRANSESS),    /* uint32_t. The maximum number of loaded
  +                                   transport sessions the TPM supports. */
  +    _ENTRY(MAX_COUNTERS),    /* uint32_t. MAx. no. of monotonic counters
  +                                   under control of TPM_CreateCounter */
  +    _ENTRY(MAX_KEYS),                /* uint32_t. The maximum number of 2048 
RSA
  +                                   keys that the TPM can support. The number
  +                                   does not include the EK or SRK. */
  +    _ENTRY(OWNER),           /* BOOL. A value of TRUE indicates that the
  +                                   TPM has successfully installed an owner. 
*/
  +    _ENTRY(CONTEXT),         /* uint32_t. The number of available saved
  +                                   session slots. This may vary with time and
  +                                   circumstances. */
  +    _ENTRY(MAX_CONTEXT),     /* uint32_t. Max. no. of saved session slots. */
  +    _ENTRY(FAMILYROWS),              /* uint32_t. The maximum number of rows 
in the
  +                                   family table */
  +    _ENTRY(TIS_TIMEOUT),     /* A 4 element array of uint32_t values each
  +                                   denoting the timeout value in microseconds
  +                                   for the following in this order:
  +                                     TIMEOUT_A, TIMEOUT_B, TIMEOUT_C, 
TIMEOUT_D 
  +                                   Where these timeouts are to be used is
  +                                   determined by the platform specific TPM
  +                                   Interface Specification. */
  +    _ENTRY(STARTUP_EFFECT),  /* The TPM_STARTUP_EFFECTS structure */
  +    _ENTRY(DELEGATE_ROW),    /* uint32_t. Max size of the delegate
  +                                   table in rows. */
  +    _ENTRY(MAX_DAASESS),     /* uint32_t. Max. number of loaded DAA sessions
  +                                   (join or sign) that the TPM supports */
  +    _ENTRY(DAASESS),         /* uint32_t. The number of available DAA
  +                                   sessions. Varies with time/circumstances 
*/
  +    _ENTRY(CONTEXT_DIST),    /* uint32_t. The maximum distance between
  +                                   context count values. MUST be >= 2^16-1. 
*/
  +    _ENTRY(DAA_INTERRUPT),   /* BOOL. A value of TRUE indicates that the
  +                                   TPM will accept ANY command while 
executing
  +                                   a DAA Join or Sign.
  +                                   A value of FALSE indicates that the TPM
  +                                   will invalidate the DAA Join or Sign upon
  +                                   the receipt of any command other than the
  +                                   next join/sign in the session or a
  +                                   TPM_SaveContext */
  +    _ENTRY(SESSIONS),                /* uint32_t. The number of available 
sessions
  +                                   from the pool. This MAY vary with time and
  +                                   circumstances. Pool sessions include
  +                                   authorization and transport sessions. */
  +    _ENTRY(MAX_SESSIONS),    /* uint32_t. The maximum number of sessions
  +                                                         the TPM supports. */
  +    _ENTRY(CMK_RESTRICTION), /* uint32_t TPM_Permanent_Data -> 
restrictDelegate */
  +    _ENTRY(DURATION),                /* A 3 element array of uint32_t values 
each
  +                                   denoting the duration value in 
microseconds
  +                                   of the duration of the three classes of
  +                                   commands: Small, Medium and Long in the
  +                                   following in this order: SMALL_DURATION,
  +                                   MEDIUM_DURATION, LONG_DURATION */
  +    _ENTRY(ACTIVE_COUNTER),  /* TPM_COUNT_ID. The id of the current
  +                                    counter. 0xff..ff if no counter is 
active */
  +    _ENTRY(MAX_NV_AVAILABLE),        /* uint32_t. Deprecated.  The maximum 
number
  +                                   of NV space that can be allocated, MAY
  +                                   vary with time and circumstances.  This
  +                                   capability was not implemented
  +                                   consistently, and is replaced by
  +                                   TPM_NV_INDEX_TRIAL. */
  +    _ENTRY(INPUT_BUFFER)     /* uint32_t. no. bytes in input buffer */
  +};
  +static size_t nTPM_CAP_PROP = sizeof(TPM_CAP_PROP) / sizeof(TPM_CAP_PROP[0]);
  +#undef       _ENTRY
   
   /*==============================================================*/
  +
  +struct matrix {
  +    uint32_t cap;
  +    uint32_t subcap_size;
  +    uint32_t result_size;
  +};
  +
  +#define TYPE_BOOL          (1 << 0)
  +#define TYPE_STRUCTURE     (1 << 1)
  +#define TYPE_UINT32        (1 << 2)
  +#define TYPE_UINT32_ARRAY  (1 << 3)
  +#define TYPE_VARIOUS       (1 << 4)
  +
  +static const struct matrix matrx[] = 
  +{
  +     {TPM_CAP_ORD              , 4, TYPE_BOOL},
  +     {TPM_CAP_ALG              , 4, TYPE_BOOL},
  +     {TPM_CAP_PID              , 2, TYPE_BOOL},
  +     {TPM_CAP_FLAG             , 4, TYPE_STRUCTURE},
  +     {TPM_CAP_PROPERTY         , 4, TYPE_VARIOUS},
  +     {TPM_CAP_VERSION          , 0, TYPE_UINT32},
  +     {TPM_CAP_KEY_HANDLE       , 0, TYPE_STRUCTURE},
  +     {TPM_CAP_CHECK_LOADED     , 4, TYPE_BOOL},
  +     {TPM_CAP_KEY_STATUS       , 4, TYPE_BOOL},
  +     {TPM_CAP_NV_LIST          , 0, TYPE_UINT32_ARRAY},
  +     {TPM_CAP_MFR              , 4, TYPE_VARIOUS},
  +     {TPM_CAP_NV_INDEX         , 4, TYPE_STRUCTURE},
  +     {TPM_CAP_TRANS_ALG        , 4, TYPE_BOOL},
  +//   {TPM_CAP_GPIO_CHANNEL     , 2, TYPE_BOOL},
  +     {TPM_CAP_HANDLE           , 4, TYPE_STRUCTURE},
  +     {TPM_CAP_TRANS_ES         , 2, TYPE_BOOL},
  +//   {TPM_CAP_MANUFACTURER_VER , 0, TYPE_STRUCTURE},
  +     {TPM_CAP_AUTH_ENCRYPT     , 4, TYPE_BOOL},
  +     {TPM_CAP_SELECT_SIZE      , 4, TYPE_BOOL},
  +     {TPM_CAP_VERSION_VAL      , 0, TYPE_STRUCTURE},
  +     {TPM_CAP_FLAG_PERMANENT   , 0, TYPE_STRUCTURE},
  +     {TPM_CAP_FLAG_VOLATILE    , 0, TYPE_STRUCTURE},
  +     {TPM_CAP_DA_LOGIC         , 2, TYPE_STRUCTURE},
  +     {-1,-1,-1}
  +};
  +
  +static const struct matrix mfr_matrix[] = {
  +     {TPM_CAP_PROCESS_ID       , 0, TYPE_UINT32},
  +     {-1,-1,-1}
  +};
  +
  +static uint32_t sikeyhandle = 0;
  +static char * sikeypass = NULL;
  +static uint32_t cap;
  +static uint32_t scap = -1;
  +#if 0
  +static uint32_t sscap = -1;
  +#endif
  +
  +static inline const char * TorF(int flag)
  +{
  +    return (flag ? "TRUE" : "FALSE");
  +}
  +
  +static void showPermanentFlags(TPM_PERMANENT_FLAGS *pf, uint32_t size)
  +{
  +    printf("Permanent flags:\n");
  +    /* rev 62 + */
  +    printf("Disabled: %s\n", TorF(pf->disable));
  +    printf("Ownership: %s\n", TorF(pf->ownership));
  +    printf("Deactivated: %s\n", TorF(pf->deactivated));
  +    printf("Read Pubek: %s\n", TorF(pf->readPubek));
  +    printf("Disable Owner Clear: %s\n",  TorF(pf->disableOwnerClear));
  +    printf("Allow Maintenance: %s\n", TorF(pf->allowMaintenance));
  +    printf("Physical Presence Lifetime Lock: %s\n", 
TorF(pf->physicalPresenceLifetimeLock));
  +    printf("Physical Presence HW Enable: %s\n", 
TorF(pf->physicalPresenceHWEnable));
  +    printf("Physical Presence CMD Enable: %s\n",  
TorF(pf->physicalPresenceCMDEnable));
  +    printf("CEKPUsed: %s\n",  TorF(pf->CEKPUsed));
  +    printf("TPMpost: %s\n", TorF(pf->TPMpost));
  +    printf("TPMpost Lock: %s\n",  TorF(pf->TPMpostLock));
  +    printf("FIPS: %s\n", TorF(pf->FIPS));
  +    printf("Operator: %s\n",  TorF(pf->tpmOperator));
  +    printf("Enable Revoke EK: %s\n", TorF(pf->enableRevokeEK));
  +
  +    /* Atmel rev 85 only returns 18 BOOLs */
  +    if (size > 19) {
  +     printf("NV Locked: %s\n", TorF(pf->nvLocked));
  +     printf("Read SRK pub: %s\n", TorF(pf->readSRKPub));
  +     printf("TPM established: %s\n", TorF(pf->tpmEstablished));
  +    }
  +
  +    /* rev 85 + */
  +    if (size > 20)
  +     printf("Maintenance done: %s\n", TorF(pf->maintenanceDone));
  +
  +    /* rev 103 */
  +    if (size > 21)
  +     printf("Disable full DA logic info: %s\n", 
TorF(pf->disableFullDALogicInfo));
  +}
  +
  +static void showVolatileFlags(TPM_STCLEAR_FLAGS * sf)
  +{
  +    printf("Volatile flags:\n");
  +    printf("Deactivated: %s\n", TorF(0 == sf->deactivated));
  +    printf("Disable ForceClear: %s\n", TorF(0 == sf->disableForceClear));
  +    printf("Physical Presence: %s\n", TorF(0 == sf->physicalPresence));
  +    printf("Physical Presence Lock: %s\n", TorF(sf->physicalPresenceLock));
  +    printf("bGlobal Lock: %s\n", TorF(sf->bGlobalLock));
  +}
  +
  +static int prepare_subcap(uint32_t cap,
  +                          struct tpm_buffer *subcap,
  +                          uint32_t scap)
  +{
  +    int handled = 0;
  +    uint32_t ret;
  +    if (TPM_CAP_CHECK_LOADED == cap) {
  +     struct keydata k = {};
  +     handled = 1;
  +     k.keyFlags = 0;
  +     k.keyUsage = TPM_KEY_LEGACY;
  +     k.pub.algorithmParms.algorithmID = scap;
  +     k.pub.algorithmParms.encScheme = TPM_ES_NONE;
  +     k.pub.algorithmParms.sigScheme = TPM_SS_RSASSAPKCS1v15_INFO;
  +     k.pub.algorithmParms.u.rsaKeyParms.keyLength = 2048   ;      /* RSA 
modulus size 2048 bits */
  +     k.pub.algorithmParms.u.rsaKeyParms.numPrimes = 2;            /* 
required */
  +     k.pub.algorithmParms.u.rsaKeyParms.exponentSize   = 0;       /* RSA 
exponent - default 0x010001 */
  +     k.pub.pubKey.keyLength = 0;       /* key not specified here */
  +     k.pub.pcrInfo.size = 0;           /* no PCR's used at this time */
  +     ret = TPM_WriteKeyInfo(subcap, &k);
  +    }
  +    return handled;
  +}
  +
  +/*==============================================================*/
  +
   static struct poptOption optionsTable[] = {
  - { "fips", '\0', POPT_ARG_VAL,          &use_fips, 1,
  -     N_("test in FIPS 140-2 mode"), NULL },
  - { "selftest", '\0', POPT_ARG_VAL,      &selftest_only, 1,
  -     N_("test in FIPS 140-2 mode"), NULL },
  +
  + { "cap", '\0', POPT_ARG_INT|POPT_ARGFLAG_ONEDASH,   &cap,   0,
  +     N_("get <capability>"),                 N_("<capability>") },
  + { "scap", '\0', POPT_ARG_INT|POPT_ARGFLAG_ONEDASH,  &scap,  0,
  +     N_("get <sub-capability>"),             N_("<sub-capability>") },
  + { "hk", '\0', POPT_ARG_INT|POPT_ARGFLAG_ONEDASH,    &sikeyhandle,   0,
  +     N_("get signing key <handle>"),         N_("<handle>") },
  + { "pwdk", '\0', POPT_ARG_STRING|POPT_ARGFLAG_ONEDASH,       &sikeypass,     
0,
  +     N_("get signing key <password>"),       N_("<password>") },
   
    { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmioAllPoptTable, 0,
           N_("Common options:"), NULL },
   
  +  POPT_AUTOALIAS
     POPT_AUTOHELP
  +
  +  { NULL, (char)-1, POPT_ARG_INCLUDE_TABLE, NULL, 0,
  +     N_("\
  +Usage: getcapability [options] -cap <capability (hex)>\n\
  +[-scap <sub cap (hex)>] [-scapd <sub cap (dec)>]\n\
  +[-hk signing key handle] [-pwdk signing key password]\n\
  +\n\
  +Possible options are:\n\
  +  -hk :   handle of a signing key if a signed response is requested\n\
  +  -pwdk : password of that signing key (if it needs one)\n\
  +"), NULL },
  +
     POPT_TABLEEND
   };
   
  -
   int main(int argc, char *argv[])
   {
  -    poptContext con = rpmioInit(argc, argv, optionsTable);
  -    rpmtpm tpm;
  -    int ec = 0;
  +    rpmtpm tpm = NULL;
  +    poptContext con;
  +    int ec = -1;             /* assume failure */
  +
  +    uint32_t ret;
  +    STACK_TPM_BUFFER(resp);
  +    int ix;
  +    STACK_TPM_BUFFER(subcap);
  +    int i;
  +     
  +    TPM_setlog(0);           /* turn off verbose output */
  +
  +    con = rpmioInit(argc, argv, optionsTable);
  +
  +    for (ix = 0; (int) matrx[ix].cap != -1; ix++) {
  +     if (cap == matrx[ix].cap)
  +         break;
  +    }
  +    if ((int) matrx[ix].cap == -1) {
  +     printf("Unknown or unsupported capability!\n");
  +     goto exit;
  +    }
  +
  +    subcap.used = 0;
  +    if (matrx[ix].subcap_size > 0) {
  +     if ((int) scap == -1) {
  +         printf("Need subcap parameter for this capability!\n");
  +         goto exit;
  +     }
  +     if (prepare_subcap(cap, &subcap, scap) == 0) {
  +         if (matrx[ix].subcap_size == 2) {
  +             STORE16(subcap.buffer, 0, scap);
  +             subcap.used = 2;
  +         } else if (matrx[ix].subcap_size >= 4) {
  +             STORE32(subcap.buffer, 0, scap);
  +             subcap.used = 4;
  +         }
  +     }
  +    }
  +
  +#if 0
  +    /* This was for VTPM extensions and needs retest */
  +    if (cap == TPM_CAP_MFR) {
  +     int idx2 = 0;
  +     while ((int) mfr_matrix[idx2].cap != -1) {
  +         if (mfr_matrix[idx2].cap == scap) {
  +             break;
  +         }
  +         idx2++;
  +     }
  +     if (mfr_matrix[idx2].subcap_size > 0) {
  +         uint32_t used = subcap.used + mfr_matrix[idx2].subcap_size;
  +         while (subcap.used < used) {
  +             if (argc <= nxtarg) {
  +                 printf("Need one more parameter for this "
  +                        "capability!\n");
  +                 exit(-1);
  +             }
  +             if (!strncmp("0x", argv[nxtarg], 2)) {
  +                 sscanf(argv[nxtarg], "%x", &sscap);
  +             } else {
  +                 sscanf(argv[nxtarg], "%d", &sscap);
  +             }
  +             nxtarg++;
  +             if (2 == matrx[ix].subcap_size) {
  +                 STORE16(subcap.buffer, subcap.used, sscap);
  +                 subcap.used += 2;
  +             } else if (matrx[ix].subcap_size >= 4) {
  +                 STORE32(subcap.buffer, subcap.used, sscap);
  +                 subcap.used += 4;
  +             }
  +         }
  +     }
  +    }
  +#endif
  +
  +    if (sikeyhandle == 0) {
  +     ret = rpmtpmErr(tpm, "GetCapability", 0,
  +             TPM_GetCapability(cap, &subcap, &resp));
  +
  +     if (ret) {
  +         printf("TPM_GetCapability returned %s.\n", TPM_GetErrMsg(ret));
  +         ec = ret;
  +         goto exit;
  +     }
  +    } else {
  +     unsigned char antiReplay[TPM_HASH_SIZE];
  +     unsigned char signature[2048];
  +     uint32_t signaturelen = sizeof(signature);
  +     pubkeydata pubkey;
  +     RSA *rsa;
  +     unsigned char sighash[TPM_HASH_SIZE];
  +     unsigned char *buffer = NULL;
  +     unsigned char *sigkeyhashptr = NULL;
  +     unsigned char sigkeypasshash[TPM_HASH_SIZE];
  +
  +     if (sikeypass) {
  +         TSS_sha1(sikeypass, strlen(sikeypass), sigkeypasshash);
  +         sigkeyhashptr = sigkeypasshash;
  +     }
  +
  +     TSS_gennonce(antiReplay);
  +
  +     ret = rpmtpmErr(tpm, "GetPubKey", 0,
  +             TPM_GetPubKey(sikeyhandle, sigkeyhashptr, &pubkey));
  +
  +     if (ret) {
  +         printf
  +             ("Error while trying to access the signing key's public 
key.\n");
  +         goto exit;
  +     }
  +
  +     rsa = TSS_convpubkey(&pubkey);
  +
  +     ret = rpmtpmErr(tpm, "GetCapabilitySigned", 0,
  +             TPM_GetCapabilitySigned(sikeyhandle,
  +                                   sigkeyhashptr,
  +                                   antiReplay,
  +                                   cap,
  +                                   &subcap,
  +                                   &resp, signature, &signaturelen));
  +
  +     if (ret) {
  +         printf("TPM_GetCapabilitySigned returned %s.\n",
  +                TPM_GetErrMsg(ret));
  +         ec = ret;
  +         goto exit;
  +     }
  +
  +     buffer = malloc(resp.used + TPM_NONCE_SIZE);
  +     if (NULL == buffer) {
  +         printf("Could not allocate buffer.\n");
  +         goto exit;
  +     }
  +     memcpy(&buffer[0], resp.buffer, resp.used);
  +     memcpy(&buffer[resp.used], antiReplay, TPM_NONCE_SIZE);
  +
  +     TSS_sha1(buffer, resp.used + TPM_NONCE_SIZE, sighash);
  +     free(buffer);
  +
  +     ret = RSA_verify(NID_sha1,
  +                      sighash, TPM_HASH_SIZE,
  +                      signature, signaturelen, rsa);
  +     if (ret != 1) {
  +         printf("Error: Signature verification failed.\n");
  +         goto exit;
  +     }
  +    }
  +
  +    if (resp.used == 0) {
  +     printf("Empty response.\n");
  +     ec = 0;
  +     goto exit;
  +    }
  +
  +    if ((int) scap == -1)
  +     printf("Result for TPM_CAP_%s(0x%x) is : ",
  +             tblName(cap, TPM_CAP, nTPM_CAP), cap);
  +    else if (cap == TPM_CAP_PROPERTY)
  +     printf("Result for TPM_CAP_%s(0x%x) %s(0x%x) is : ",
  +             tblName(cap, TPM_CAP, nTPM_CAP), cap,
  +             tblName(scap, TPM_CAP_PROP, nTPM_CAP_PROP), scap);
  +    else
  +     printf("Result for TPM_CAP_%s(0x%x), subcapability 0x%x is : ",
  +             tblName(cap, TPM_CAP, nTPM_CAP), cap, scap);
  +
  +    switch (matrx[ix].result_size) {
  +    case TYPE_BOOL:
  +     printf("%s", TorF(resp.buffer[0]));
  +     break;
  +    case TYPE_UINT32:
  +     {
  +         uint32_t rsp = LOAD32(resp.buffer, 0);
  +         printf("0x%08X  = %d\n", rsp, rsp);
  +     }   break;
  +    case TYPE_UINT32_ARRAY:
  +     printf("\n");
  +     for (i = 0; (i + 3) < (int) resp.used; i += 4) {
  +         uint32_t rsp = LOAD32(resp.buffer, i);
  +         if (cap == TPM_CAP_NV_LIST)
  +             /* don't zero extend, grep needs the exact value for test suite 
*/
  +             printf("%d. Index : %d = 0x%x.\n", (i / 4) + 1, rsp, rsp);
  +         else if (TPM_CAP_KEY_HANDLE == cap)
  +             printf("%d. keyhandle : %d.\n", (i / 4) + 1, rsp);
  +         else
  +             printf("%d. item : %d.\n", (i / 4) + 1, rsp);
  +     }
  +     break;
  +    case TYPE_STRUCTURE:
  +     switch (cap) {
  +     case TPM_CAP_FLAG:
  +         {
  +             if (scap == TPM_CAP_FLAG_PERMANENT) {
  +                 TPM_PERMANENT_FLAGS pf;
  +                 STACK_TPM_BUFFER(tb);
  +                 TSS_SetTPMBuffer(&tb, resp.buffer, resp.used);
  +                 ret = rpmtpmErr(tpm, "ReadPermanentFlags", ERR_MASK,
  +                             TPM_ReadPermanentFlags(&tb, 0, &pf, resp.used));
  +                 if ((ret & ERR_MASK) != 0 || ret > resp.used) {
  +                     printf("ret=%x, responselen=%d\n", ret, resp.used);
  +                     printf("Error parsing response!\n");
  +                     goto exit;
  +                 }
  +                 printf("\n");
  +                 showPermanentFlags(&pf, resp.used);
  +             } else if (scap == TPM_CAP_FLAG_VOLATILE) {
  +                 TPM_STCLEAR_FLAGS sf;
  +                 STACK_TPM_BUFFER(tb);
  +                 TSS_SetTPMBuffer(&tb, resp.buffer, resp.used);
  +                 ret = rpmtpmErr(tpm, "ReadSTClearFlags", ERR_MASK,
  +                             TPM_ReadSTClearFlags(&tb, 0, &sf));
  +                 if ((ret & ERR_MASK) != 0 || ret > resp.used) {
  +                     printf("ret=%x, responselen=%d\n", ret, resp.used);
  +                     printf("Error parsing response!\n");
  +                     goto exit;
  +                 }
  +                 printf("\n");
  +                 showVolatileFlags(&sf);
  +             }
  +         }
  +         break;
  +
  +     case TPM_CAP_KEY_HANDLE:
  +         {
  +             uint16_t num = LOAD16(resp.buffer, 0);
  +             uint32_t handle;
  +             printf("\n");
  +             for (i = 0; i < (int) num; i++) {
  +                 handle = LOAD32(resp.buffer, 4 * i + 2);
  +                 printf("%d. handle: 0x%08X\n", i, handle);
  +             }
  +         }
  +         break;
  +     case TPM_CAP_NV_INDEX:
  +         {
  +             TPM_NV_DATA_PUBLIC ndp;
  +             STACK_TPM_BUFFER(tb);
  +             TSS_SetTPMBuffer(&tb, resp.buffer, resp.used);
  +             ret = rpmtpmErr(tpm, "ReadNVDataPublic", ERR_MASK,
  +                             TPM_ReadNVDataPublic(&tb, 0, &ndp));
  +             if ((ret & ERR_MASK) != 0) {
  +                 printf("Could not deserialize the TPM_NV_DATA_PUBLIC 
structure.\n");
  +                 goto exit;
  +             }
  +             printf("permission.attributes : %08X\n",
  +                        (unsigned int) ndp.permission.attributes);
  +             printf("ReadSTClear           : %02X\n",
  +                        ndp.bReadSTClear);
  +             printf("WriteSTClear          : %02X\n",
  +                        ndp.bWriteSTClear);
  +             printf("WriteDefine           : %02X\n",
  +                        ndp.bWriteDefine);
  +             printf("dataSize              : %08X = %d",
  +                        (unsigned int) ndp.dataSize,
  +                        (unsigned int) ndp.dataSize);
  +         }
  +         break;
  +     case TPM_CAP_HANDLE:
  +         {
  +             uint16_t num = LOAD16(resp.buffer, 0);
  +             for (i = 0; i < (int)num; i++) {
  +                 uint32_t handle = LOAD32(resp.buffer, 4 * i + sizeof(num));
  +                 printf("%02d. 0x%08X\n", i, handle);
  +             }
  +         }
  +         break;
  +     case TPM_CAP_VERSION_VAL:
  +         {
  +             TPM_CAP_VERSION_INFO cvi;
  +             STACK_TPM_BUFFER(tb);
  +             TSS_SetTPMBuffer(&tb, resp.buffer, resp.used);
  +             ret = rpmtpmErr(tpm, "ReadCapVersionInfo", ERR_MASK,
  +                             TPM_ReadCapVersionInfo(&tb, 0, &cvi));
  +             if ((ret & ERR_MASK) != 0) {
  +                 printf ("Could not read the version info structure.\n");
  +                 goto exit;
  +             }
  +
  +             printf("\n");
  +             printf("major      : 0x%02X\n", cvi.version.major);
  +             printf("minor      : 0x%02X\n", cvi.version.minor);
  +             printf("revMajor   : 0x%02X\n", cvi.version.revMajor);
  +             printf("revMinor   : 0x%02X\n", cvi.version.revMinor);
  +             printf("specLevel  : 0x%04X\n", cvi.specLevel);
  +             printf("errataRev  : 0x%02X\n", cvi.errataRev);
  +
  +             printf("VendorID   : ");
  +             for (i = 0; i < 4; i++)
  +                 printf("%02X ", cvi.tpmVendorID[i]);
  +             printf("\n");
  +             /* Print vendor ID in text if printable */
  +             for (i = 0; i < 4; i++) {
  +                 if (isprint(cvi.tpmVendorID[i])) {
  +                     if (i == 0)
  +                         printf("VendorID   : ");
  +                     printf("%c", cvi.tpmVendorID[i]);
  +                 } else
  +                     break;
  +             }
  +             printf("\n");
  +
  +             printf("[not displaying vendor specific information]\n");
  +         }
  +         break;
  +#if 0                /* kgold: I don't think these are valid cap values */
  +     case TPM_CAP_FLAG_PERMANENT:
  +         {
  +             TPM_PERMANENT_FLAGS pf;
  +             STACK_TPM_BUFFER(tb);
  +             TSS_SetTPMBuffer(&tb, resp.buffer, resp.used);
  +
  +             if (resp.used == 21)
  +                 ret = TPM_ReadPermanentFlagsPre103(&tb, 0, &pf);
  +             else
  +                 ret = TPM_ReadPermanentFlags(&tb, 0, &pf);
  +
  +             if ((ret & ERR_MASK) != 0 || ret > resp.used) {
  +                 printf("ret=%x, responselen=%d\n", ret, resp.used);
  +                 printf("Error parsing response!\n");
  +                 goto exit;
  +             }
  +
  +             printf("\n");
  +             showPermanentFlags(&pf, resp.used);
  +         }
  +         break;
  +
  +     case TPM_CAP_FLAG_VOLATILE:
  +         {
  +             TPM_STCLEAR_FLAGS sf;
  +             STACK_TPM_BUFFER(tb);
  +             TSS_SetTPMBuffer(&tb, resp.buffer, resp.used);
  +             ret = TPM_ReadSTClearFlags(&tb, 0, &sf);
  +             if ((ret & ERR_MASK) != 0 || ret > resp.used) {
  +                 printf("ret=%x, responselen=%d\n", ret, resp.used);
  +                 printf("Error parsing response!\n");
  +                 goto exit;
  +             }
  +
  +             printf("\n");
  +             showVolatileFlags(&sf);
  +         }
  +         break;
  +#endif
  +     case TPM_CAP_DA_LOGIC:
  +         {
  +             TPM_BOOL lim = FALSE;
  +             TPM_DA_INFO dainfo;
  +             TPM_DA_INFO_LIMITED dainfo_lim;
  +             STACK_TPM_BUFFER(tb);
  +             TSS_SetTPMBuffer(&tb, resp.buffer, resp.used);
  +             ret = rpmtpmErr(tpm, "ReadDAInfo", ERR_MASK,
  +                             TPM_ReadDAInfo(&tb, 0, &dainfo));
  +             if ((ret & ERR_MASK) != 0 || ret > resp.used) {
  +                 ret = rpmtpmErr(tpm, "ReadDAInfoLimited", ERR_MASK,
  +                             TPM_ReadDAInfoLimited(&tb, 0, &dainfo_lim));
  +                 if ((ret & ERR_MASK) != 0 || ret > resp.used) {
  +                     printf("ret=%x, responselen=%d\n", ret,
  +                                resp.used);
  +                     printf("Error parsing response!\n");
  +                     goto exit;
  +                 }
  +                 lim = TRUE;
  +             }
  +
  +             printf("\n");
  +             if (lim) {
  +                 printf("State      : %d\n", dainfo_lim.state);
  +                 printf("Actions    : 0x%08x\n",
  +                            dainfo_lim.actionAtThreshold.actions);
  +
  +                 for (i = 0; i < (int)dainfo_lim.vendorData.size; i++)
  +                     printf("%02x ", (dainfo_lim.vendorData.buffer[i]&0xff));
  +             } else {
  +                 printf("State              : %d\n", dainfo.state);
  +                 printf("currentCount       : %d\n",
  +                            dainfo.currentCount);
  +                 printf("thresholdCount     : %d\n",
  +                            dainfo.thresholdCount);
  +                 printf("Actions            : 0x%08x\n",
  +                            dainfo.actionAtThreshold.actions);
  +                 printf("actionDependValue  : %d\n",
  +                            dainfo.actionDependValue);
  +
  +#if 0
  +                 for (i = 0; i < (int)dainfo_lim.vendorData.size; i++)
  +                     printf("%02x ", (dainfo_lim.vendorData.buffer[i]&0xff));
  +#endif
  +             }
  +         }
  +         break;
  +     }
  +     break;
  +    case TYPE_VARIOUS:
  +     switch (cap) {
  +
  +     case TPM_CAP_MFR:
  +         switch (scap) {
  +         case TPM_CAP_PROCESS_ID:
  +             printf("%d\n", LOAD32(resp.buffer, 0));
  +             break;
  +         }
  +         break;              /* TPM_CAP_MFR */
  +
  +     default:
  +         switch (scap) {
  +         case TPM_CAP_PROP_OWNER:            /* booleans */
  +         case TPM_CAP_PROP_DAA_INTERRUPT:
  +             printf("%s", TorF(resp.buffer[0]));
  +             break;
  +#if 0
  +         case TPM_CAP_PROP_TIMEOUTS:
  +#endif
  +         case TPM_CAP_PROP_TIS_TIMEOUT:      /* array of 4 UINTs */
  +             for (i = 0; i < 4; i++)
  +                 printf("%d ", LOAD32(resp.buffer, 4 * i));
  +             break;
  +         case TPM_CAP_PROP_STARTUP_EFFECT:
  +           {
  +             TPM_STARTUP_EFFECTS se = 0;
  +             ret = rpmtpmErr(tpm, "ReadStartupEffects", ERR_MASK,
  +                             TPM_ReadStartupEffects(resp.buffer, &se));
  +             if ((ret & ERR_MASK) != 0) {
  +                 printf("Could not read startup effects structure.\n");
  +                 goto exit;
  +             }
  +             printf("0x%08X=%d\n", (unsigned int) se, (unsigned int) se);
  +             printf("\n");
  +             printf("Startup effects:\n");
  +             printf("Effect on audit digest: %s\n",
  +                     (se & (1 << 7)) ? "none" : "active");
  +             printf("Audit Digest on TPM_Startup(ST_CLEAR): %s\n",
  +                     (se & (1 << 6)) ? "set to NULL" : "not set to NULL");
   
  -    tpm = rpmtpmNew(NULL, 0);
  +             printf("Audit Digest on TPM_Startup(any)     : %s\n",
  +                     (se & (1 << 5)) ? "set to NULL" : "not set to NULL");
  +             printf("TPM_RT_KEY resource initialized on TPM_Startup(ST_ANY)  
   : %s\n",
  +                     (se & (1 << 4)) ? "yes" : "no");
  +             printf("TPM_RT_AUTH resource initialized on 
TPM_Startup(ST_STATE)  : %s\n",
  +                     (se & (1 << 3)) ? "yes" : "no");
  +             printf("TPM_RT_HASH resource initialized on 
TPM_Startup(ST_STATE)  : %s\n",
  +                     (se & (1 << 2)) ? "yes" : "no");
  +             printf("TPM_RT_TRANS resource initialized on 
TPM_Startup(ST_STATE) : %s\n",
  +                     (se & (1 << 1)) ? "yes" : "no");
  +             printf("TPM_RT_CONTEXT session initialized on 
TPM_Startup(ST_STATE): %s",
  +                     (se & (1 << 0)) ? "yes" : "no");
  +           } break;
  +         case TPM_CAP_PROP_DURATION:         /* array of 3 UINTs */
  +             for (i = 0; i < 3; i++)
  +                 printf("%d ", LOAD32(resp.buffer, 4 * i));
  +             break;
  +         case TPM_CAP_PROP_ACTIVE_COUNTER:
  +           { uint32_t val = LOAD32(resp.buffer, 0);
  +             printf("0x%08X=%d", val, val);
  +             if (val == 0xffffffff)
  +                 printf(" (no counter is active)");
  +           } break;
  +         default:    /* single UINT32 */
  +           { uint32_t val = LOAD32(resp.buffer, 0);
  +             printf("%u=0x%08X", val, val);
  +           } break;
  +         }
  +     }
  +     printf("\n");
  +     break;
  +    }
   
  -    tpm = rpmtpmFree(tpm);
  +    printf("\n");
  +    ec = 0;
   
  +exit:
       con = rpmioFini(con);
   
       return ec;
  @@ .
______________________________________________________________________
RPM Package Manager                                    http://rpm5.org
CVS Sources Repository                                [email protected]

Reply via email to