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

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

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

先再次贴出该函数源码:

static bool tpm2_tool_onstart(tpm2_options **opts) {

    static struct option topts[] = {
      { "parent-auth",    required_argument, NULL, 'P' },
      { "key-auth",       required_argument, NULL, 'p' },
      { "hash-algorithm", required_argument, NULL, 'g' },
      { "key-algorithm",  required_argument, NULL, 'G' },
      { "attributes",     required_argument, NULL, 'a' },
      { "sealing-input",  required_argument, NULL, 'i' },
      { "policy",         required_argument, NULL, 'L' },
      { "public",         required_argument, NULL, 'u' },
      { "private",        required_argument, NULL, 'r' },
      { "parent-context", required_argument, NULL, 'C' },
      { "key-context",    required_argument, NULL, 'c' },
      { "creation-data",  required_argument, NULL,  0  },
      { "template-data",  required_argument, NULL,  1  },
      { "creation-ticket",required_argument, NULL, 't' },
      { "creation-hash",  required_argument, NULL, 'd' },
      { "outside-info",   required_argument, NULL, 'q' },
      { "pcr-list",       required_argument, NULL, 'l' },
      { "cphash",         required_argument, NULL,  2  },
      { "rphash",         required_argument, NULL,  3  },
      { "session",        required_argument, NULL, 'S' },
      { "format",         required_argument, NULL, 'f' },
      { "output",         required_argument, NULL, 'o' },
    };

    *opts = tpm2_options_new("P:p:g:G:a:i:L:u:r:C:c:t:d:q:l:S:o:f:",
    ARRAY_LEN(topts), topts, on_option, NULL, 0);

    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/tpm_create.c)中,如下:

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

    switch (key) {
    case 'P':
        ctx.parent.auth_str = value;
        break;
    case 'p':
        ctx.object.auth_str = value;
        break;
    case 'g':
        ctx.object.name_alg = value;
        break;
    case 'G':
        ctx.object.alg = value;
        ctx.object.is_object_alg_specified = true;
        break;
    case 'a':
        ctx.object.attrs = value;
        break;
    case 'i':
        ctx.object.sealed_data = strcmp("-", value) ? value : NULL;
        ctx.object.alg = "keyedhash";
        ctx.object.is_sealing_input_specified = true;
        bool res = load_sensitive();
        if (!res) {
            return false;
        }
        break;
    case 'L':
        ctx.object.policy = value;
        break;
    case 'u':
        ctx.object.public_path = value;
        break;
    case 'r':
        ctx.object.private_path = value;
        break;
    case 'C':
        ctx.parent.ctx_path = value;
        break;
    case 'c':
        ctx.object.ctx_path = value;
        break;
    case 0:
        ctx.object.creation_data_file = value;
        break;
    case 1:
        ctx.object.template_data_path = value;
        break;
    case 't':
        ctx.object.creation_ticket_file = value;
        break;
    case 'd':
        ctx.object.creation_hash_file = value;
        break;
    case 'q':
        ctx.object.outside_info_data = value;
        break;
    case 'l':
        if (!pcr_parse_selections(value, &ctx.object.creation_pcr)) {
            LOG_ERR("Could not parse pcr selections, got: \"%s\"", value);
            return false;
        }
        break;
    case 2:
        ctx.cp_hash_path = value;
        break;
    case 3:
        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 {
            LOG_ERR("Specify a max of 3 sessions");
            return false;
        }
        break;
    case 'f':
        ctx.format = tpm2_convert_pubkey_fmt_from_optarg(value);
        if (ctx.format == pubkey_format_err) {
            return false;
        }
        ctx.format_set = true;
        break;
    case 'o':
        ctx.output_path = value;
        break;
        /* no default */
    };

    return true;
}

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

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

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

其中的参数说明如下:

OPTIONS

These options for creating the TPM entity:

  • -C--parent-context=OBJECT:

    The parent of the object to be created. —— 要创建的对象的父级。

  • -P--parent-auth=AUTH:

    The authorization value of the parent object specified with -C. —— 使用-C指定的父对象的授权值。

  • -p--key-auth=AUTH:

    The authorization value for the created object. —— 创建对象的授权值。

  • -g--hash-algorithm=ALGORITHM:

    The hash algorithm for generating the objects name. This is optional and defaults to sha256 when not specified. —— 用于生成对象名称的哈希算法。这是可选的,未指定时默认为sha256。

  • -G--key-algorithm=ALGORITHM:

    The key algorithm associated with this object. It defaults to "rsa" if not specified. —— 与此对象关联的密钥算法。如果未指定,则默认为“rsa”。

  • -a--attributes=ATTRIBUTES:

    The object attributes, optional. The default for created objects is: —— 对象属性,可选。默认为:

    TPMA_OBJECT_SIGN_ENCRYPT|TPMA_OBJECT_DECRYPT|TPMA_OBJECT_FIXEDTPM| TPMA_OBJECT_FIXEDPARENT|TPMA_OBJECT_SENSITIVEDATAORIGIN| TPMA_OBJECT_USERWITHAUTH

    When -i is specified for sealing, TPMA_OBJECT_SIGN_ENCRYPT and TPMA_OBJECT_DECRYPT are removed from the default attribute set. The algorithm is set in a way where the the object is only good for sealing and unsealing. I.e. one cannot use an object for sealing and cryptography operations. —— 当 –i 被指定为密封时,TPMA_OBJECT_SIGN_ENCRYPT 和TPMA_OBJECT_DECRYPT从默认属性集中删除。该算法以对象仅对密封和解封有效的方式设置。即不能使用对象进行密封加密操作。

    When -L is specified for adding policy based authorization information AND no string password is specified, the attribute TPMA_OBJECT_USERWITHAUTH is cleared unless an explicit choice is made by setting of the attribute with -a option. This prevents creation of objects with inadvertent auth model where in user intended to enforce a policy but inadvertently created an object with empty auth which can be used instead of policy authorization. —— 指定-L并且未指定字符串密码为添加基于策略的授权信息时,除非通过使用-a选项设置属性做出明确选择,否则将清除属性TPMA_OBJECT_USERWITHAUTH。这可以防止创建具有无意身份验证模型的对象,其中用户打算强制执行策略,但无意中创建了具有空身份验证的对象,该对象可用于代替策略授权。

  • -i--sealing-input=FILE or STDIN:

    The data file to be sealed, optional. If file is -, read from stdin. When sealing data only the TPM_ALG_KEYEDHASH algorithm with a NULL scheme is allowed. Thus, -G cannot be specified. —— 要密封的数据文件,可选。如果文件是 -,从标准输入读取。密封数据时,仅允许使用 NULL 方案的TPM_ALG_KEYEDHASH算法。因此,无法指定-G 。

  • -L--policy=FILE or HEX_STRING:

    The input policy file or a hex string, optional. —— 输入策略文件,可选。

  • -u--public=FILE:

    The output file which contains the public portion of the created object, optional. —— 包含已创建对象的公共部分的输出文件,可选。

  • -r--private=FILE:

    The output file which contains the sensitive portion of the object, optional.  —— 包含对象敏感部分的输出文件,可选。可以移出TPM的对象需要受到保护其机密性和完整性。此blob包含对象的敏感部分。对象的敏感部分受到父对象的保护,使用父对象的对称加密细节来加密敏感数据并对其进行HMAC。

  • -c--key-context=FILE:

    The output file which contains the key context, optional. The key context is analogous to the context file produced by tpm2_load(1), however is generated via a tpm2_createloaded(1) command. This option can be used to avoid the normal tpm2_create(1) and tpm2_load(1) command sequences and do it all in one command, atomically. —— 包含密钥上下文的输出文件,可选。key-context类似于tpm2_load生成的上下文文件,但是是通过tpm2_createloaded命令生成的。此选项可用于避免正常的tpm2_create和tpm2_load命令序列,并以原子方式在一个命令中完成所有操作。

  • --creation-data=FILE:

    An optional file output that saves the creation data for certification. —— 一个可选的文件输出,保存创建数据以供认证。

    • --template-data=FILE:

    An optional file output that saves the key template data (TPM2B_PUBLIC) to be used in tpm2_policytemplate. —— 一个可选的文件输出,保存要在tpm2_policytemplate中使用的密钥模板数据 (TPM2B_PUBLIC) 。

  • -t--creation-ticket=FILE:

    An optional file output that saves the creation ticket for certification. —— 一个可选的文件输出,用于保存创建ticket以供认证。

  • -d--creation-hash=FILE:

    An optional file output that saves the creation hash for certification. —— 一个可选的文件输出,用于保存创建哈希以供认证。

  • -q--outside-info=HEX_STR_OR_FILE:

    An optional hex string or path to add unique data to the creation data. Note that it does not contribute in creating statistically unique object. —— 用于将唯一数据添加到创建数据的可选十六进制字符串或路径。它不会有助于创建统计上唯一的对象。

  • -l--pcr-list=PCR:

    The list of PCR banks and selected PCRs' ids for each bank to be included in the creation data for certification. —— PCR banks列表和每个banks的选定 PCR 的 ID ,将包含在创建数据中以进行认证。

  • --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. —— 记录命令参数哈希的文件路径。这通常称为cpHash。注意:选择此选项时,该工具不会实际执行命令,它只是返回一个cpHash。

  • --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创建的会话。可以指定其中的多个。例如,您可以有一个会话用于审计,另一个用于参数的加密/解密。

pubkey options

Public key format.
  • -o--output=FILE:

    The output file path, recording the public portion of the object. —— 输出文件路径,记录对象的公共部分。

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_create.c中的tpm2_tool_onstart函数就基本分析完了。

你可能感兴趣的:(TPM,TPM,tpm2-tools)