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

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

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

tpm2-tools代码链接:GitHub - tpm2-software/tpm2-tools: The source repository for the Trusted Platform Module (TPM2.0) tools

先来看第一段代码:

// Register this tool with tpm2_tool.c
TPM2_TOOL_REGISTER("getrandom", 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_getrandom.c也可以说tpm2_getrandom命令中,宏展开后为:

static const tpm2_tool tool = { 
		.name		= getrandom, 
		.onstart	= tpm2_tool_onstart, 
		.onrun		= tpm2_tool_onrun, 
		.onstop		= tpm2_tool_onstop, 
		.onexit		= 0, 
	}; 
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中实现,代码如下:

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_getrandom.c,来看具体的几个函数。

(1)tpm2_tool_onstart

tpm2_tool_onstart函数代码如下:

static bool tpm2_tool_onstart(tpm2_options **opts) {

    const struct option topts[] = {
        { "output",       required_argument, NULL, 'o' },
        { "force",        required_argument, NULL, 'f' },
        { "hex",          no_argument,       NULL,  0  },
        { "session",      required_argument, NULL, 'S' },
        { "cphash",       required_argument, NULL,  1  },
        { "rphash",       required_argument, NULL,  2  }
    };

    *opts = tpm2_options_new("S:o:f", ARRAY_LEN(topts), topts, on_option, on_args,
            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
     */

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

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

    /*
     * 4. Process outputs
     */
    return process_outputs();
}

(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
     */

    /*
     * 3. Close auxiliary sessions
     */
    tool_rc rc = tool_rc_success;
    tool_rc tmp_rc = tool_rc_success;
    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;
}

后续文章对这几个函数进行深入解析。

猜你喜欢

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