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

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

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

先再次贴出该函数源码:

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

    UNUSED(flags);

    /*
     * 1. Process options
     */
    tool_rc rc = check_options(ectx);
    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 = load(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_options函数的作用是选项检查与处理。它在同文件(tpm2_load.c)中,代码如下:

static tool_rc check_options(ESYS_CONTEXT *ectx) {

    UNUSED(ectx);

    tool_rc rc = tool_rc_success;
    if (!ctx.object.privpath) {
        LOG_ERR("Expected private object portion via -r");
        rc = tool_rc_option_error;
    }

    /*
     * Check for TSS PEM file input:
     *  1. It is specified with the -r,--private option alone.
     *  2. The parent and public objects are implicit and read directly from
     *     the TSS PEM.
     */
    ctx.is_tss_pem =
        (!ctx.parent.ctx_path && !ctx.object.pubpath && ctx.object.privpath);

    if (!ctx.is_tss_pem) {
        if (!ctx.parent.ctx_path) {
            LOG_ERR("Expected parent object via -C or a PEM file with -r");
            rc = tool_rc_option_error;
        }

        if (!ctx.object.pubpath) {
            LOG_ERR("Expected public object portion via -u or a PEM file with -r");
            rc = tool_rc_option_error;
        }
    }

    if (!ctx.contextpath && !ctx.cp_hash_path) {
        LOG_ERR("Expected option -c");
        rc = tool_rc_option_error;
    }

    if (ctx.contextpath && ctx.cp_hash_path) {
        LOG_ERR("Cannot output contextpath when calculating cp_hash");
        rc = tool_rc_option_error;
    }

    return rc;
}

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

static tpm_load_ctx ctx = {
    .parameter_hash_algorithm = TPM2_ALG_ERROR,
};

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

typedef struct tpm_tool_ctx tpm_load_ctx;
struct tpm_tool_ctx {
    /*
     * Inputs
     */
    struct {
        const char *ctx_path;
        const char *auth_str;
        tpm2_loaded_object object;
    } parent;

    struct {
        const char *pubpath;
        TPM2B_PUBLIC public;
        const char *privpath;
        TPM2B_PRIVATE private;
        ESYS_TR handle;
    } object;

    bool is_tss_pem;

    /*
     * Outputs
     */
    const char *namepath;
    const char *contextpath;

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

回到check_options函数中,一上来先做检查,要求ctx.object.privpath不能为空。ctx.object.privpath在tpm2_tool_onstart函数中的tpm2_options_new函数中设置的on_option函数中赋值(详见前一篇文章)。实际上是要求命令行必须带有“-r FILE”或“--private=FILE”

接下来检查TSS PEM文件输入。代码片断如下:

  /*
     * Check for TSS PEM file input:
     *  1. It is specified with the -r,--private option alone.
     *  2. The parent and public objects are implicit and read directly from
     *     the TSS PEM.
     */
    ctx.is_tss_pem =
        (!ctx.parent.ctx_path && !ctx.object.pubpath && ctx.object.privpath);

ctx.is_tss_pem的值只在ctx.parent.ctx_path为空并且ctx.object.pubpath为空并且ctx.object.privpath不为空的情况下才能为真,其它情况都为假。ctx.object.privpath上边检查中已经保证了;ctx.parent.ctx_path的值是通过命令行带上“-C OBJECT”或“--parent-context=OBJECT”选项传入的;而ctx.object.pubpath则是通过命令行带上“-u FILE”或“--public=FILE”选项传入的。

接下来,如果ctx.is_tss_pem为假,则要求ctx.parent.ctx_path必须不为空并且tx.object.pubpath也必须不为空,即命令行中必须带有“-C OBJECT”或“--parent-context=OBJECT”和-u FILE”或“--public=FILE”。

最后检查的ctx.contextpath与ctx.cp_hash_path之间的相互约束,代码片断如下:

 if (!ctx.contextpath && !ctx.cp_hash_path) {
        LOG_ERR("Expected option -c");
        rc = tool_rc_option_error;
    }

    if (ctx.contextpath && ctx.cp_hash_path) {
        LOG_ERR("Cannot output contextpath when calculating cp_hash");
        rc = tool_rc_option_error;
    }

ctx.contextpath和ctx.cp_hash_path不能同时为空,也不能同时不为空。这就是说命令行选项中“-c, --key-context=FILE”与“--cphash=FILE”必须指定其一。

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

猜你喜欢

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