TPM 2.0 の tpm2_rsaencrypt コマンドに対応するソース ファイルは tpm2_rsaencrypt.c で、tpm2-tools/tools/ にあり、合計 169 行あります (バージョン 5.5)。
tpm2_rsaencrypt の機能は、TPM を使用して RSA 暗号化操作を実行することです。IETF RFC 3447 (PKCS#1) に従って、指定されたパディング スキームを使用してファイル データの内容に対して RSA 暗号化を実行します。
以下では、いくつかの記事の長さを利用して、tpm2_rsaencrypt コマンドと組み合わせた tpm2_rsaencrypt.c ファイルの詳細かつ完全な分析を実行します。
最初のコード部分を見てみましょう。
// Register this tool with tpm2_tool.c
TPM2_TOOL_REGISTER("rsaencrypt", tpm2_tool_onstart, tpm2_tool_onrun, NULL, 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_rsaencrypt.c では、tpm2_rsaencrypt コマンドのマクロ展開が次のようになっているとも言えます。
static const tpm2_tool tool = {
.name = "rsaencrypt",
.onstart = tpm2_tool_onstart,
.onrun = tpm2_tool_onrun,
.onstop = NULL,
.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_rsaencrypt.c に戻って、特定の関数を確認します。
(1)tpm2_tool_onstart
tpm2_tool_onstart 関数のコードは次のとおりです。
static bool tpm2_tool_onstart(tpm2_options **opts) {
static const struct option topts[] = {
{"output", required_argument, NULL, 'o'},
{"key-context", required_argument, NULL, 'c'},
{"scheme", required_argument, NULL, 's'},
{"label", required_argument, NULL, 'l'},
};
*opts = tpm2_options_new("o:c:s:l:", 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 *context, tpm2_option_flags flags) {
UNUSED(flags);
tool_rc rc = init(context);
if (rc != tool_rc_success) {
return rc;
}
return rsa_encrypt_and_save(context);
}
後続の記事では、これらの機能の詳細な分析を提供します。