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

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

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

先再次贴出该函数源码:

static tool_rc tpm2_tool_onrun(ESYS_CONTEXT *ectx, tpm2_option_flags flags) {

    UNUSED(flags);

    /*
     * 1. Process options
     */
    tool_rc rc = check_options();
    if (rc != tool_rc_success) {
        return rc;
    }

    /*
     * 2. Process inputs
     */
    rc = process_inputs(ectx);
    if (rc != tool_rc_success) {
        return rc;
    }

    /*
     * 3. TPM2_CC_<command> call
     */
    rc = create(ectx);
    if (rc != tool_rc_success) {
        return rc;
    }

    /*
     * 4. Process outputs
     */
    return process_output(ectx);
}

根据tpm2_tool_onrun函数中的注释,此函数分为4个步骤即调用了4个函数:check_options、process_inputs、load、process_outputs。实际上这个流程也是一个通用流程。

(1)check_options函数

check_option函数的作用是选项检查与处理。它在同文件(tpm2_create.c)中,代码如下:

static tool_rc check_options(void) {

    if (!ctx.parent.ctx_path) {
        LOG_ERR("Must specify parent object via -C.");
        return tool_rc_option_error;
    }

    if (ctx.object.is_sealing_input_specified && ctx.object.is_object_alg_specified) {
        LOG_ERR("Cannot specify -G and -i together.");
        return tool_rc_option_error;
    }

    if (ctx.cp_hash_path && !ctx.rp_hash_path &&
       (ctx.object.public_path || ctx.object.private_path ||
        ctx.object.creation_data_file || ctx.object.creation_hash_file ||
        ctx.object.creation_ticket_file || ctx.object.ctx_path)) {
        LOG_ERR("CpHash Error: Cannot specify pub, priv, creation - data, hash, ticket");
        return tool_rc_option_error;
    }

    if (ctx.format_set && !ctx.output_path) {
        LOG_ERR("Cannot specify --format/-f without specifying --output/-o");
        return tool_rc_option_error;
    }

    return tool_rc_success;
}

重点说一下ctx。ctx在同文件(tools/tpm2_create.c)中定义并初始化,代码如下:

#define DEFAULT_KEY_ALG "rsa2048"

static tpm_create_ctx ctx = {
        .object = {
            .alg = DEFAULT_KEY_ALG,
            .creation_pcr = { .count = 0 },
            .object_handle = ESYS_TR_NONE,
            .outside_info.size = 0,
        },
        .aux_session_handle[0] = ESYS_TR_NONE,
        .aux_session_handle[1] = ESYS_TR_NONE,
        .cp_hash.size = 0,
        .is_command_dispatch = true,
        .parameter_hash_algorithm = TPM2_ALG_ERROR,
        .format = pubkey_format_tss,
};

ctx是tpm_create_ctx结构的成员,该结构也在同文件中定义,代码如下:

typedef struct tpm_create_ctx tpm_create_ctx;
#define MAX_AUX_SESSIONS 2
#define MAX_SESSIONS 3
struct tpm_create_ctx {
        /*
         * Inputs
         */
    struct {
        const char *ctx_path;
        const char *auth_str;
        tpm2_loaded_object object;
    } parent;

    struct {
        char *sealed_data;
        char *auth_str;
        TPM2B_SENSITIVE_CREATE sensitive;
        TPM2B_PUBLIC in_public;
        TPM2B_DATA outside_info;
        TPML_PCR_SELECTION creation_pcr;
        char *outside_info_data;
        char *alg;
        char *attrs;
        char *name_alg;
        char *policy;
        bool is_object_alg_specified;
        bool is_sealing_input_specified;

        /*
         * Outputs
         */
        char *public_path;
        TPM2B_PUBLIC *out_public;
        const char *ctx_path;
        char *private_path;
        TPM2B_PRIVATE *out_private;
        char *creation_data_file;
        TPM2B_CREATION_DATA *creation_data;
        char *creation_hash_file;
        TPM2B_DIGEST *creation_hash;
        char *creation_ticket_file;
        TPMT_TK_CREATION *creation_ticket;
        char *template_data_path;
        ESYS_TR object_handle;
    } object;

    bool is_createloaded;

    /*
     * Parameter hashes
     */
    const char *cp_hash_path;
    TPM2B_DIGEST cp_hash;
    const char *rp_hash_path;
    TPM2B_DIGEST rp_hash;
    TPMI_ALG_HASH parameter_hash_algorithm;
    bool is_command_dispatch;

    /*
     * Aux sessions
     */
    uint8_t aux_session_cnt;
    tpm2_session *aux_session[MAX_AUX_SESSIONS];
    const char *aux_session_path[MAX_AUX_SESSIONS];
    ESYS_TR aux_session_handle[MAX_AUX_SESSIONS];

    /*
     * Formated public key output
     */
    char *output_path;
    bool format_set;
    tpm2_convert_pubkey_fmt format;
};

回到check_options函数中,一上来先做检查,要求ctx.parent.ctx_path(要创建的对象的父级)必须不能为空。接下来要求ctx.object.is_sealing_input_specified(要密封的数据文件)和ctx.object.is_object_alg_specified(与此对象关联的密钥算法)不能同时指定。

再往下是一个大段判断,意思是当ctx.cp_hash_path(记录命令参数哈希的文件路径)不为空即被指定,并且ctx.rp_hash_path(记录响应参数哈希的文件路径)为空即未被指定时,ctx.object.public_path(包含已创建对象的公共部分的输出文件)、ctx.object.private_path(包含对象敏感部分的输出文件)、ctx.object.creation_data_file(保存创建数据以供认证的文件)、ctx.object.creation_hash_file(用于保存创建哈希以供认证的文件)、ctx.object.creation_ticket_file(保存创建ticket以供认证的文件)、ctx.object.ctx_path(包含密钥上下文的输出文件)都必须为空。

ctx.cp_hash_path、ctx.rp_hash_path等成员均在tpm2_tool_onstart函数中的tpm2_options_new函数中设置的on_option函数中赋值(详见前一篇文章)。实际上是要求命令行在带有“--cphash=FILE”且为带有“--rphash=FILE”时必须不能带有“--public=FILE(-u FILE)”、--private=FILE(-r FILE)”、“--creation-data=FILE”、“--creation-hash=FILE(-d FILE)”、“--creation-ticket=FILE(-t FILE)”、“--key-context=FILE(-c FILE)”。

接下来继续进行参数检查。要求当ctx.format_set(公钥输出文件的格式选择)不为空时ctx.output_path(记录对象的公共部分的文件路径)必须也不为空。ctx.format_set、ctx.output_path也是在tpm2_tool_onstart函数中的tpm2_options_new函数中设置的on_option函数中赋值(详见前一篇文章)。实际上是要求命令行在带有“--format=FILE(-f FILE)”时必须带有“---output=FILE(-o FILE)”。

至此,tpm2_tool_onrun函数的第1个函数check_options函数就分析完了。下一篇文章起分析余下的函数。

猜你喜欢

转载自blog.csdn.net/phmatthaus/article/details/130149647
今日推荐