> 文章列表 > tpm2-tools源码分析之tpm2_create.c(3)

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

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函数就分析完了。下一篇文章起分析余下的函数。