tpm2-tools源码分析之tpm2_nvdefine.c(2)

接前一篇文章:tpm2-tools源码分析之tpm2_nvdefine.c(1)

本文对tpm2_nvdefine.c中的tpm2_tool_onstart函数进行详细解析。

先再次贴出该函数源码:

static bool tpm2_tool_onstart(tpm2_options **opts) {

    const struct option topts[] = {
        { "hierarchy",      required_argument, NULL, 'C' },
        { "size",           required_argument, NULL, 's' },
        { "attributes",     required_argument, NULL, 'a' },
        { "hierarchy-auth", required_argument, NULL, 'P' },
        { "hash-algorithm", required_argument, NULL, 'g' },
        { "index-auth",     required_argument, NULL, 'p' },
        { "policy",         required_argument, NULL, 'L' },
        { "cphash",         required_argument, NULL,  0  },
        { "rphash",         required_argument, NULL,  1  },
        { "session",        required_argument, NULL, 'S' },
    };

    *opts = tpm2_options_new("S:C:s:a:P:p:L:g:", ARRAY_LEN(topts), topts,
        on_option, on_arg, TPM2_OPTIONS_OPTIONAL_SAPI_AND_FAKE_TCTI);

    return *opts != NULL;
}

tpm2_options结构的定义在tpm2-tools/lib/tpm2_options.h中,代码如下:

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;

struct option的定义在/usr/include/bits/getopt_ext.h中,代码如下:

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;
};

on_option函数的实现在同文件(tools/tpm2_nvdefine.c)中,如下:

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

    bool result;

    switch (key) {
    case 'C':
        ctx.auth_hierarchy.ctx_path = value;
        break;
    case 'P':
        ctx.auth_hierarchy.auth_str = value;
        break;
    case 's':
        ctx.size_set = true;
        result = tpm2_util_string_to_uint16(value, &ctx.size);
        if (!result) {
            LOG_ERR("Could not convert size to number, got: \"%s\"", value);
            return false;
        }
        break;
    case 'a':
        result = tpm2_util_string_to_uint32(value, &ctx.nv_attribute);
        if (!result) {
            result = tpm2_attr_util_nv_strtoattr(value, &ctx.nv_attribute);
            if (!result) {
                LOG_ERR(
                        "Could not convert NV attribute to number or keyword, got: \"%s\"",
                        value);
                return false;
            }
        }
        break;
    case 'p':
        ctx.index_auth_str = value;
        break;
    case 'L':
        ctx.policy_file = value;
        break;
    case 0:
        ctx.cp_hash_path = value;
        break;
    case 1:
        ctx.rp_hash_path = value;
        break;
    case 'S':
        ctx.aux_session_path[ctx.aux_session_cnt] = value;
        if (ctx.aux_session_cnt < MAX_AUX_SESSIONS) {
            ctx.aux_session_cnt++;
        } else {
            return false;
        }
        break;
    case 'g':
        ctx.halg = tpm2_alg_util_from_optarg(value,
                tpm2_alg_util_flags_hash);
        if (ctx.halg == TPM2_ALG_ERROR) {
            LOG_ERR("Invalid choice for name digest hash algorithm");
            return false;
        }
        break;
    }

    return true;
}

要更好地理解这些选项乃至tpm2_tool_onstart函数的功能,需要与tpm2_nvdefine命令的说明相结合来看。tpm2_nvdefine命令的详细说明参见:

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

下载了源码后,在tpm2-tools/man/tpm2_nvdefine.1.md中。

其中的参数说明如下:

OPTIONS

  • -C--hierarchy=OBJECT:

    Specifies the handle used to authorize. Defaults to oTPM_RH_OWNER, when no value has been specified. Supported options are: —— 指定用于授权的句柄。当未指定任何值时,默认为o,TPM_RH_OWNER。支持的选项包括:

    • o for TPM_RH_OWNER
    • p for TPM_RH_PLATFORM
    • <num> where a hierarchy handle or nv-index may be used.
  • -s--size=NATURAL_NUMBER:

    Specifies the size of data area in bytes. Defaults to MAX_NV_INDEX_SIZE which is typically 2048. —— 指定数据区域的大小(以字节为单位)。默认为MAX_NV_INDEX_SIZE,通常为2048。

  • -g--hash-algorithm=ALGORITHM:

    The hash algorithm used to compute the name of the Index and used for the authorization policy. If the index is an extend index, the hash algorithm is used for the extend. —— 用于计算索引名称并用于授权策略的哈希算法。如果索引是扩展索引,则使用哈希算法进行扩展。

  • -a--attributes=ATTRIBUTES

    Specifies the attribute values for the nv region used when creating the entity. Either the raw bitfield mask or "nice-names" may be used. See section "NV Attributes" for more details. If not specified, the attributes default to various selections based on the hierarchy the index is defined in. —— 指定创建实体时使用的nv区域的属性值。可以使用原始位字段掩码或“nice-names”。如果未指定,则属性默认为基于层级的各种选择,索引在层级中定义。

    For the owner hiearchy the defaults are: —— 对于所有者等级,默认值为:

    • TPMA_NV_OWNERWRITE
    • TPMA_NV_OWNERREAD

    For the platform hiearchy, the defaults are: —— 对于平台等级,默认值为:

    • TPMA_NV_PPWRITE
    • TPMA_NV_PPREAD

    If a policy file is specified, the hiearchy chosen default attributes are bitwise or'd with: —— 如果指定了策略文件,则所选层级的默认属性是按位计算的或与以下属性一起使用:

    • TPMA_NV_POLICYWRITE
    • TPMA_NV_POLICYREAD

    If a policy file is NOT specified, the hiearchy chosen default attributes are bitwise or'd with: —— 如果未指定策略文件,则所选层级的默认属性是按位计算的或与以下属性一起使用:

    • TPMA_NV_AUTHWRITE
    • TPMA_NV_AUTHREAD
  • -P--hierarchy-auth=AUTH:

    Specifies the authorization value for the hierarchy. Authorization values should follow the "authorization formatting standards", see section "Authorization Formatting". —— 指定层次结构的授权值。

  • -p--index-auth=AUTH:

    Specifies the password of NV Index when created. HMAC and Password authorization values should follow the "authorization formatting standards", see section "Authorization Formatting". —— 指定创建NV索引时的密码。

  • -L--policy=FILE:

    Specifies the policy digest file for policy based authorizations. —— 指定基于策略的授权的策略摘要文件。

  • --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, unless rphash is also required. —— 用于记录命令参数哈希的文件路径。这通常被称为cpHash。注意:当此选项被选择时,此工具将不会实际执行命令,它只是返回一个cpHash,除非也需要rphash。

  • --rphash=FILE

    File path to record the hash of the response parameters. This is commonly termed as rpHash. —— 用于记录响应参数哈希的文件路径。这通常被称为rpHash。

  • -S--session=FILE:

    The session created using tpm2_startauthsession. Multiple of these can be specified. For example, you can have one session for auditing and another for encryption/decryption of the parameters. —— 使用tpm2_startauthsession创建的会话。可以指定多个。

  • ARGUMENT the command line argument specifies the NV index or offset number. —— 命令行参数指定NV索引或偏移量编号。

tpm2_options_new函数属于公共代码,在tpm2-tools/lib/tpm2_options.c中,代码如下:

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;
}

tpm2_new_options函数很容易理解,其功能是基于tpm2_tool_onstart函数中的struct option topts构建tpm2_options实例(*opts)。

至此,tpm2_nvdefine.c中的tpm2_tool_onstart函数就基本分析完了。

猜你喜欢

转载自blog.csdn.net/phmatthaus/article/details/130687344