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

tpm2_verifysignature的功能是使用TPM验证签名。使用加载的密钥验证带有传递给TPM的消息摘要的消息上的签名。

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

先来看第一段代码:
 

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

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_verifysignature.c也可以说tpm2_verifysignature命令中,宏展开后为:

static const tpm2_tool tool = {
    .name		= "verifysignature",
	.onstart	= tpm2_tool_onstart,
	.onrun		= tpm2_tool_onrun,
	.onstop		= NULL,
	.onexit		= tpm2_tool_onexit,
};
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;

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

(1)tpm2_tool_onstart

tpm2_tool_onstart函数代码如下:

static bool tpm2_tool_onstart(tpm2_options **opts) {

    const struct option topts[] = {
            { "digest",         required_argument, NULL, 'd' },
            { "hash-algorithm", required_argument, NULL, 'g' },
            { "message",        required_argument, NULL, 'm' },
            { "format",         required_argument, NULL,  0  },
            { "scheme",         required_argument, NULL, 'f' },
            { "signature",      required_argument, NULL, 's' },
            { "ticket",         required_argument, NULL, 't' },
            { "key-context",    required_argument, NULL, 'c' },
    };


    *opts = tpm2_options_new("g:m:d:f:s:t:c:", 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 *context, tpm2_option_flags flags) {

    UNUSED(flags);

    /* initialize and process */
    tool_rc rc = init(context);
    if (rc != tool_rc_success) {
        return rc;
    }

    rc = verify_signature(context);
    if (rc != tool_rc_success) {
        LOG_ERR("Verify signature failed!");
        return rc;
    }

    return tool_rc_success;
}

(3)tpm2_tool_onexit

tpm2_tool_onexit函数代码如下:

static void tpm2_tool_onexit(void) {
    if (ctx.msg_hash) {
        free(ctx.msg_hash);
    }
}

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

05-12 21:54