tpm2_nvundefine.c of tpm2-tools source code analysis (2)

Continued from the previous article: tpm2_nvundefine.c of tpm2-tools source code analysis (1)

This article analyzes the tpm2_tool_onstart function in tpm2_nvundefine.c in detail.

First post the source code of the function again:

static bool tpm2_tool_onstart(tpm2_options **opts) {
/*
 * The tool does both undefine and undefine space special and so the options
 * are interpreted accordingly.
 * 
 * Case NV_Undefine:
 *       1. 'C' and 'P' correspond to either TPM2_RH_OWNER or TPM2_RH_PLATFORM
 *       2. In this case, two aux sessions are allowed.
 * Case NV_UndefineSpaceSpecial:
 *       1. 'S' is for the NV-Index --> Object#1, Session#1.
 *       2. 'C' and 'P' is defaulted to TPM2_RH_PLATFORM --> Object#2, Session#2
 *       3. In this case, just one aux session is allowed.
 *       4. Additional option --with-policydelete is required with tcti=none as
 *          the NV index isn't available to read the attribute when only
 *          calculating cpHash and command is not dispatched.
 */
    const struct option topts[] = {
        { "hierarchy",          required_argument, NULL, 'C' },
        { "auth",               required_argument, NULL, 'P' },
        { "session",            required_argument, NULL, 'S' },
        { "cphash",             required_argument, NULL,  0  },
        { "rphash",             required_argument, NULL,  1  },
        { "with-policydelete",  no_argument,       NULL,  2  },
        { "name",               required_argument, NULL, 'n' },
    };
 
    *opts = tpm2_options_new("C:P:S:n:", ARRAY_LEN(topts), topts, on_option,
        on_arg, TPM2_OPTIONS_OPTIONAL_SAPI_AND_FAKE_TCTI);
 
    return *opts != NULL;
}

The definition of the tpm2_options structure is in tpm2-tools/lib/tpm2_options.h, the code is as follows:

struct tpm2_options {
    struct {
        tpm2_option_handler on_opt;
        tpm2_arg_handler on_arg;
    } callbacks;
    char *short_opts;
    size_t len;
    uint32_t flags;
    struct option long_opts[];
};
 
typedef struct tpm2_options tpm2_options;

The definition of struct option is in /usr/include/bits/getopt_ext.h, the code is as follows:

struct option
{
  const char *name;
  /* has_arg can't be an enum because some compilers complain about
     type mismatches in all the code that assumes it is an int.  */
  int has_arg;
  int *flag;
  int val;
};

The implementation of the on_option function is in the same file (tools/tpm2_nvundefine.c), as follows:

static bool on_option(char key, char *value) {

    switch (key) {
    case 'C':
        ctx.is_auth_hierarchy_specified = true;
        ctx.auth_hierarchy.ctx_path = value;
        break;
    case 'P':
        ctx.auth_hierarchy.auth_str = value;
        break;
    case 'S':
        /*
         * In case of undefinespacespecial first session is expected to satisfy
         * the ADMIN role in a policycommandcode session.
         */
        if (!ctx.aux_session_cnt) {
            ctx.policy_session.path = value;   
        }
        ctx.aux_session_path[ctx.aux_session_cnt] = value;
        if (ctx.aux_session_cnt < MAX_AUX_SESSIONS) {
            ctx.aux_session_cnt++;
        } else {
            LOG_ERR("Specify a max of 3 sessions");
            return false;
        }
        break;
    case 0:
        ctx.cp_hash_path = value;
        break;
    case 1:
        ctx.rp_hash_path = value;
        break;
    case 2:
        ctx.has_policy_delete_set = true;
        break;
    case 'n':
        ctx.precalc_nvname.size = BUFFER_SIZE(TPM2B_NAME, name);
        int q = tpm2_util_hex_to_byte_structure(value, &ctx.precalc_nvname.size,
        ctx.precalc_nvname.name);
        if (q) {
            LOG_ERR("FAILED: %d", q);
            return false;
        }
        break;
    }

    return true;
}

To better understand the functions of these options and even the tpm2_tool_onstart function, it needs to be combined with the description of the tpm2_nvundefine command. For a detailed description of the tpm2_nvundefine command, see:

tpm2-tools/tpm2_nvundefine.1.md at master · tpm2-software/tpm2-tools · GitHub

After downloading the source code, it is in tpm2-tools/man/tpm2_nvundefine.1.md.

The parameters are described as follows:

OPTIONS

  • -C--hierarchy=OBJECT:

    Specifies the hierarchy used to authorize. Supported options are: —— Specifies the hierarchy used to authorize. The supported options are:

    • o for TPM_RH_OWNER
    • p for TPM_RH_PLATFORM
    • <num> where a hierarchy handle may be specified.
  • -P--auth=AUTH:

    Specifies the authorization value for the hierarchy. —— Specifies the authorization value for the hierarchy.

  • -S--session=POLICY_SESSION:

    Specify a policy session to use when the NV index has attribute  TPMA_NV_POLICY_DELETE set. This can also be used to specify an auxiliary session for auditing and or encryption/decryption of the parameters. Note: —— Specify to use when the NV index has attribute TPMA_NV_policy_DELETE set policy session. This can also be used to specify secondary sessions for auditing and/or encryption/decryption of parameters. Notice:

    1. If TPM2_CC_NV_UndefineSpaceSpecial is invoked then only one additional aux session can be specified. The order of how sessions are specified also matters. First specification of is interpreted  -S as the session for satisfying the ADMIN role required for TPM2_CC _NV_UndefineSpaceSpecial. - If TPM2_CC_NV_UndefineSpaceSpecial is called, only An additional auxiliary session can be specified. The order in which sessions are specified is also important. The first specification of -S is interpreted as a session satisfying the ADMIN role required by TPM2_CC_NV_UndefineSpaceSpecial.

    2. If TPM2_CC_NV_Undefine is invoked then only two additional aux sessions can be specified.

  • --cphash=FILE

    File path to record the hash of the command parameters. This is commonly termed as cpHash. NOTE: When this option is selected, The tool will not actually execute the command, it simply returns a cpHash, it simply returns a cpHash unless rphash is also required. – Path to file to record hash of command arguments. This is often called cpHash. NOTE: When this option is selected, this tool will not actually execute the command, it will just return a cpHash, unless rphash is also required.

  • --rphash=FILE

    File path to record the hash of the response parameters. This is commonly termed as rpHash. This is often called rpHash.

  • --with-policydelete=NONE

    This must be specified when calculating cpHash with  --tcti=none . This is a requirement because there is no way to know if the attribute TPMA_NV_POLICYDELETE has been set from the NV index name alone. —— Dangdang uses --tcpi=none to calculate cpHash , this must be specified. This is a requirement because there is no way to know if the attribute TPMA_NV_POLICYDELETE is set from just the NV index name.

  • -n--name=FILE:

    The name of the NV index that must be provided when only calculating the cpHash without actually dispatching the command to the TPM. —— The name of the NV index that must be provided when only calculating the cpHash without actually dispatching the command to the TPM.

  • ARGUMENT  the command line argument specifies the NV index or offset number. —— The command line argument specifies the NV index or offset number.

The tpm2_options_new function belongs to the public code. In tpm2-tools/lib/tpm2_options.c, the code is as follows:

tpm2_options *tpm2_options_new(const char *short_opts, size_t len,
        const struct option *long_opts, tpm2_option_handler on_opt,
        tpm2_arg_handler on_arg, uint32_t flags) {
 
    tpm2_options *opts = calloc(1, sizeof(*opts) + (sizeof(*long_opts) * len));
    if (!opts) {
        LOG_ERR("oom");
        return NULL;
    }
 
    /*
     * On NULL, just make it a zero length string so we don't have to keep
     * checking it for NULL.
     */
    if (!short_opts) {
        short_opts = "";
    }
 
    opts->short_opts = strdup(short_opts);
    if (!opts->short_opts) {
        LOG_ERR("oom");
        free(opts);
        return NULL;
    }
 
    opts->callbacks.on_opt = on_opt;
    opts->callbacks.on_arg = on_arg;
    opts->len = len;
    opts->flags = flags;
    memcpy(opts->long_opts, long_opts, len * sizeof(*long_opts));
 
    return opts;
}

The tpm2_new_options function is easy to understand, and its function is to construct a tpm2_options instance (*opts) based on the struct option topts in the tpm2_tool_onstart function.

So far, the tpm2_tool_onstart function in tpm2_nvundefine.c is basically analyzed.

おすすめ

転載: blog.csdn.net/phmatthaus/article/details/130710533