tpm2-tools源码分析之tpm2_createprimary.c(1)
TPM 2.0中的tpm2_createprimary命令对应的源文件就是tpm2_createprimary.c,该文件位于tpm2-tools/tools/下,一共有450行(版本5.5)。
tpm2_createprimary的功能是创建一个主密钥。命令描述为:此命令用于在以下层次结构之一下创建主对象:所有者、平台、背书、NULL。该命令将创建并加载主对象。敏感和公共部分不返回信息。已创建对象句柄的上下文文件保存为文件,以供将来与创建的主对象交互。
下边用几篇文章的篇幅对tpm2_createprimary.c文件结合tpm2_createprimary命令进行深入的、完全的解析。
先来看第一段代码:
// Register this tool with tpm2_tool.c
TPM2_TOOL_REGISTER("createprimary", tpm2_tool_onstart, tpm2_tool_onrun,
tpm2_tool_onstop, 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_createprimary.c也可以说tpm2_createprimary命令中,宏展开后为:
static const tpm2_tool tool = {
.name = createprimary,
.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_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_createprimary.c,来看具体的几个函数。
(1)tpm2_tool_onstart
tpm2_tool_onstart函数代码如下:
static bool tpm2_tool_onstart(tpm2_options **opts) {
const struct option topts[] = {
{ "hierarchy", required_argument, 0, 'C' },
{ "hierarchy-auth", required_argument, 0, 'P' },
{ "key-auth", required_argument, 0, 'p' },
{ "hash-algorithm", required_argument, 0, 'g' },
{ "key-algorithm", required_argument, 0, 'G' },
{ "key-context", required_argument, 0, 'c' },
{ "policy", required_argument, 0, 'L' },
{ "attributes", required_argument, 0, 'a' },
{ "unique-data", required_argument, 0, 'u' },
{ "creation-data", required_argument, 0, 0 },
{ "template-data", required_argument, 0, 1 },
{ "creation-ticket",required_argument, 0, 't' },
{ "creation-hash", required_argument, 0, 'd' },
{ "outside-info", required_argument, 0, 'q' },
{ "pcr-list", required_argument, 0, 'l' },
{ "cphash", required_argument, 0, 2 },
{ "format", required_argument, 0, 'f' },
{ "output", required_argument, 0, 'o' },
};
*opts = tpm2_options_new("C:P:p:g:G:c:L:a:u:t:d:q:l:o:f:", ARRAY_LEN(topts),
topts, on_option, 0, 0);
return *opts != 0;
}
(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(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 = createprimary(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 = tpm2_session_close(&ctx.auth_hierarchy.object.session);
/*
* 3. Close auxiliary sessions
*/
return rc;
}
(4)tpm2_tool_onexit
tpm2_tool_onexit函数代码如下:
static void tpm2_tool_onexit(void) {
tpm2_hierarchy_pdata_free(&ctx.objdata);
}
后续文章对这几个函数进行深入解析。
相关文章
- Android源码学习之环境搭建(Ubuntu下载Android源码)
- 【Redis源码】Redis 启动过程分析
- Postgresql源码(69)常规锁简单分析
- 在线客服系统源码开发实战总结:Golang实现对接微信公众号网页授权接口功能
- Spring IOC 容器源码分析
- vue源码分析-响应式系统(三)
- React源码分析4-深度理解diff算法
- React源码分析5-commit6
- selenium源码通读·13 |webdriver/support分析
- HIKARI源码之-ConcurrentBag简单分析
- webpack原理(3):Tapable源码分析及钩子函数作用分析
- 【Android Protobuf 序列化】Protobuf 使用 ( Protobuf 源码分析 | 创建 Protobuf 对象 )
- 【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 一 )
- 【Android 事件分发】ItemTouchHelper 事件分发源码分析 ( 绑定 RecyclerView )
- 【Android 逆向】ART 函数抽取加壳 ① ( ART 下的函数抽取恢复时机 | 禁用 dex2oat 机制源码分析 )
- 【Linux 内核 内存管理】mmap 系统调用源码分析 ③ ( vm_mmap_pgoff 函数执行流程 | vm_mmap_pgoff 函数源码 )
- ArrayList源码解析详解编程语言
- 耗子练手速小游戏,初学者拿去练手吧(附带源码)
- 分析Linux内核初始化过程源码剖析(linuxinit源码)
- MySQL源码分析:深入理解数据库引擎(mysqlsrc)
- Redis 源码下载:一站式服务(redis 源码下载)
- 深入研究Redis源码分析(源码分析redis)
- jQuery源码分析笔记(2)变量列表
- jQuery源码分析笔记(4)Ready函数
- jQuery插件-jRating评分插件源码分析及使用方法