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

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

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

TPM 2.0中的tpm2_create命令对应的源文件就是tpm2_create.c,该文件位于tpm2-tools/tools/下,一共有671行(版本5.5)。

tpm2_create的功能是创建一个密钥。命令描述为:创建一个子对象。该对象可以是钥匙或密封对象。密封对象允许将用户数据密封到TPM,最大大小为128字节。另外,如果指定了-c,它将加载创建的对象。

下边用几篇文章的篇幅对tpm2_create.c文件结合tpm2_create命令进行深入的、完全的解析。

先来看第一段代码

// Register this tool with tpm2_tool.c
TPM2_TOOL_REGISTER("create", tpm2_tool_onstart, tpm2_tool_onrun,
tpm2_tool_onstop, NULL)

TPM2_TOOL_REGISTER是一个宏定义,在tpm2-tools/tools/tpm2_tool.h中,代码如下:

#define TPM2_TOOL_REGISTER(tool_name,tool_onstart,tool_onrun,tool_onstop,tool_onexit) \\static const tpm2_tool tool = { \\.name		= tool_name, \\.onstart	= tool_onstart, \\.onrun		= tool_onrun, \\.onstop		= tool_onstop, \\.onexit		= tool_onexit, \\}; \\static void \\__attribute__((__constructor__)) \\__attribute__((__used__)) \\_tpm2_tool_init(void) \\{ \\tpm2_tool_register(&tool); \\}

TPM2_TOOLS_REGISTER宏定义是整个tpm2-tools中的命令所共用的,是一个框架性质的代码。

在本文件tpm2_create.c也可以说tpm2_create命令中,宏展开后为:

static const tpm2_tool tool = {.name		= create,.onstart	= tool_onstart,.onrun		= tool_onrun,.onstop		= tool_onstop,.onexit		= NULL,
};
static void__attribute__((__constructor__))__attribute__((__used__))_tpm2_tool_init(void)
{tpm2_tool_register(&tool);
}

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

typedef struct {const char * name;tpm2_tool_onstart_t onstart;tpm2_tool_onrun_t onrun;tpm2_tool_onstop_t onstop;tpm2_tool_onexit_t onexit;
} tpm2_tool;

其中包含的相关函数指针如下(同文件中,就在上边):

/*** An optional interface for tools to specify what options they support.* They are concatenated with main's options and passed to getopt_long.* @param opts*  The callee can choose to set *opts to a tpm_options pointer allocated*  via tpm2_options_new(). Setting *opts to NULL is not an error, and*  Indicates that no options are specified by the tool.** @return*  True on success, false on error.*/
typedef bool (*tpm2_tool_onstart_t)(tpm2_options **opts);/*** This is the main interface for tools, after tcti and sapi/esapi initialization* are performed.* @param ectx*  The system/esapi api context.* @param flags*  Flags that tools may wish to respect.* @return*  A tool_rc indicating status.*/
typedef tool_rc (*tpm2_tool_onrun_t)(ESYS_CONTEXT *ectx, tpm2_option_flags flags);/*** Called after tpm2_tool_onrun() is invoked. ESAPI context is still valid during this call.* @param ectx*  The system/esapi api context.* @return*  A tool_rc indicating status.*/
typedef tool_rc (*tpm2_tool_onstop_t)(ESYS_CONTEXT *ectx);/*** Called when the tool is exiting, useful for cleanup.*/
typedef void (*tpm2_tool_onexit_t)(void);

tpm2_tool_register函数在tpm2-tools/tools/tpm2_tools.c中实现,代码如下:

/** Build a list of the TPM2 tools linked into this executable*/
#ifndef TPM2_TOOLS_MAX
#define TPM2_TOOLS_MAX 1024
#endif
static const tpm2_tool *tools[TPM2_TOOLS_MAX];
static unsigned tool_count;void tpm2_tool_register(const tpm2_tool *tool) {if (tool_count < TPM2_TOOLS_MAX) {tools[tool_count++] = tool;} else {LOG_ERR("Over tool count");abort();}
}

回到tpm2_create.c,来看具体的几个函数。

(1)tpm2_tool_onstart

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

(2)tpm2_tool_onrun

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

(3)tpm2_tool_onstop

tpm2_tool_onstop函数代码如下:

static tool_rc tpm2_tool_onstop(ESYS_CONTEXT *ectx) {UNUSED(ectx);/** 1. Free objects*//** 2. Close authorization sessions*/tool_rc rc = tool_rc_success;tool_rc tmp_rc = tpm2_session_close(&ctx.parent.object.session);if (tmp_rc != tool_rc_success) {rc = tmp_rc;}/** 3. Close auxiliary sessions*/size_t i = 0;for(i = 0; i < ctx.aux_session_cnt; i++) {if (ctx.aux_session_path[i]) {tmp_rc = tpm2_session_close(&ctx.aux_session[i]);if (tmp_rc != tool_rc_success) {rc = tmp_rc;}}}return rc;
}

(4)tpm2_tool_onexit

tpm2_tool_onexit函数在tpm2_create.c即tpm2_create命令中并未实现(TPM2_TOOL_REGISTER的时候传入的值为NULL)。