SM2密钥对生成
Closed this issue · 15 comments
怎么使用TPM2-TSS的ESYS API生成SM2密钥对?使用Esys_CreatePrimary或者Esys_Create具体怎么生成SM2密钥对?
對於 ECC 金鑰,您可以使用 .curveID =TPM2_ECC_SM2_P256 作為 inPublic 參數。
看起來擁有者層次結構 (ESYS_TR_RH_OWNER) 的授權不起作用。
大佬,您给看下,这个如何做才能生成SM2密钥对呢
TPM2中是否支持SM2算法跟TPM2芯片本身有关系吗
以下示例基于在 libtpms 上运行的 TSS 集成测试。
TSS2_RC r;
ESYS_TR objectHandle = ESYS_TR_NONE;
TPM2B_PUBLIC *outPublic = NULL;
TPM2B_CREATION_DATA *creationData = NULL;
TPM2B_DIGEST *creationHash = NULL;
TPMT_TK_CREATION *creationTicket = NULL;
TPM2B_SENSITIVE_CREATE inSensitive = {
.size = 0,
.sensitive = {
.userAuth = {
.size = 0,
.buffer = {0}
,
},
.data = {
.size = 0,
.buffer = {0}
}
}
};
TPM2B_PUBLIC inPublicECC = {
.size = 0,
.publicArea = {
.type = TPM2_ALG_ECC,
.nameAlg = TPM2_ALG_SHA256,
.objectAttributes = (TPMA_OBJECT_USERWITHAUTH |
TPMA_OBJECT_RESTRICTED |
TPMA_OBJECT_SIGN_ENCRYPT |
TPMA_OBJECT_FIXEDTPM |
TPMA_OBJECT_FIXEDPARENT |
TPMA_OBJECT_SENSITIVEDATAORIGIN),
.authPolicy = {
.size = 0,
},
.parameters.eccDetail = {
.symmetric = {
.algorithm = TPM2_ALG_NULL,
.keyBits.aes = 128,
.mode.aes = TPM2_ALG_CFB,
},
.scheme = {
.scheme = TPM2_ALG_ECDSA,
.details = {.ecdsa =
{.hashAlg = TPM2_ALG_SHA256}
}
},
.curveID = TPM2_ECC_SM2_P256,
.kdf = {.scheme =
TPM2_ALG_NULL,
.details = {}
}
},
.unique.ecc = {
.x = {.size = 0,.buffer = {}},
.y = {.size = 0,.buffer = {}}
}
,
}
};
TPM2B_DATA outsideInfo = {
.size = 0,
.buffer = {}
,
};
TPML_PCR_SELECTION creationPCR = {
.count = 0,
};
r = Esys_CreatePrimary(esys_context, ESYS_TR_RH_OWNER, ESYS_TR_PASSWORD,
ESYS_TR_NONE, ESYS_TR_NONE, &inSensitive, &inPublicECC,
&outsideInfo, &creationPCR, &objectHandle,
&outPublic, &creationData, &creationHash,
&creationTicket);
按照您这种方式,还是报错,我是用c++开发在ubuntu24.04系统上安装配置了最新的tpm2-tss,然后如下实现方式:
#include <iostream>
#include <string>
#include <iomanip>
#include <tss2/tss2_esys.h>
#include <tss2/tss2_common.h>
#include <tss2/tss2_tpm2_types.h>
#include <tss2/tss2_fapi.h>
void test() {
TSS2_RC rc;
// 1.初始化TPM2
ESYS_CONTEXT *esys_context = nullptr;
TSS2_TCTI_CONTEXT *tcti = nullptr;
TSS2_ABI_VERSION *abiVersion = nullptr;
rc = Esys_Initialize(&esys_context, tcti, abiVersion);
if (rc != TSS2_RC_SUCCESS) {
// 错误处理
std::cout << "Esys_Initialize---》初始化失败,错误码: " << rc << std::endl;
} else {
std::cout << "Esys_Initialize---》初始化成功!" << std::endl;
}
// 2.创建密钥对
TPM2B_SENSITIVE_CREATE inSensitive;
inSensitive.size = 0;
inSensitive.sensitive.userAuth.size = 0;
inSensitive.sensitive.userAuth.buffer[0] = {};
inSensitive.sensitive.data.size = 0;
inSensitive.sensitive.data.buffer[0] = {};
TPM2B_PUBLIC inPublic;
inPublic.size = 0;
inPublic.publicArea.type = TPM2_ALG_ECC;
inPublic.publicArea.nameAlg = TPM2_ALG_SHA256;
inPublic.publicArea.objectAttributes = (TPMA_OBJECT_USERWITHAUTH |
TPMA_OBJECT_RESTRICTED |
TPMA_OBJECT_SIGN_ENCRYPT |
TPMA_OBJECT_FIXEDTPM |
TPMA_OBJECT_FIXEDPARENT |
TPMA_OBJECT_SENSITIVEDATAORIGIN);
inPublic.publicArea.authPolicy.size = 0;
inPublic.publicArea.parameters.eccDetail.symmetric.algorithm = TPM2_ALG_NULL;
inPublic.publicArea.parameters.eccDetail.symmetric.keyBits.aes = 128;
inPublic.publicArea.parameters.eccDetail.symmetric.mode.aes = TPM2_ALG_CFB;
inPublic.publicArea.parameters.eccDetail.scheme.scheme = TPM2_ALG_ECDSA;
inPublic.publicArea.parameters.eccDetail.scheme.details.ecdsa.hashAlg = TPM2_ALG_SHA256;
inPublic.publicArea.parameters.eccDetail.curveID = TPM2_ECC_SM2_P256;
inPublic.publicArea.parameters.eccDetail.kdf.scheme = TPM2_ALG_NULL;
inPublic.publicArea.parameters.eccDetail.kdf.details = {};
inPublic.publicArea.unique.ecc.x.size = 0;
inPublic.publicArea.unique.ecc.x.buffer[0] = {};
inPublic.publicArea.unique.ecc.y.size = 0;
inPublic.publicArea.unique.ecc.y.buffer[0] = {};
TPM2B_DATA outsideInfo = {0, {}};
TPML_PCR_SELECTION creationPCR;
creationPCR.count = 0;
ESYS_TR objectHandle = ESYS_TR_NONE;
TPM2B_PUBLIC *outPublic = nullptr;
TPM2B_CREATION_DATA *creationData = nullptr;
TPM2B_DIGEST *creationHash = nullptr;
TPMT_TK_CREATION *creationTicket = nullptr;
rc = Esys_CreatePrimary(esys_context,
ESYS_TR_RH_OWNER,
ESYS_TR_PASSWORD,
ESYS_TR_NONE,
ESYS_TR_NONE,
&inSensitive,
&inPublic,
&outsideInfo,
&creationPCR,
&objectHandle,
&outPublic,
&creationData,
&creationHash,
&creationTicket);
if (rc != TSS2_RC_SUCCESS) {
std::cout << "Esys_CreatePrimary---》创建密钥对失败,错误码: " << rc << std::endl;
} else {
std::cout << "Esys_CreatePrimary---》创建密钥对成功!" << std::endl;
}
// 释放分配的内存
rc = Esys_FlushContext(esys_context, objectHandle);
if (esys_context) Esys_Finalize(&esys_context);
Esys_Free(esys_context);
Esys_Free(outPublic);
Esys_Free(creationData);
Esys_Free(creationHash);
Esys_Free(creationTicket);
}
int main()
{
test();
return 0;
}
我电脑是戴尔台式机,安装的是ubuntu24.04,按照您上面说的示例基于在 libtpms 上运行的 TSS 集成测试
因此您的筆記型電腦的 TPM 不支援 TPM2_ECC_SM2_P256。要對此進行測試,您可以使用 libtpms 作為 TPM 模擬器。
我使用上面的 esys 示例和 tpm 工具创建了一个主数据库。 tpm 工具的示例 从 github 安装 litpms:
tpm2_startup -c -Tlibtpms:tpm_state
tpm2_createprimary -G ecc_sm2_p256 -Tlibtpms:tpm_state
name-alg:
value: sha256
raw: 0xb
attributes:
value: fixedtpm|fixedparent|sensitivedataorigin|userwithauth|restricted|decrypt
raw: 0x30072
type:
value: ecc
raw: 0x23
curve-id:
value: SM2 p256
raw: 0x20
kdfa-alg:
value: null
raw: 0x10
kdfa-halg:
value: (null)
raw: 0x0
scheme:
value: null
raw: 0x10
scheme-halg:
value: (null)
raw: 0x0
sym-alg:
value: aes
raw: 0x6
sym-mode:
value: cfb
raw: 0x43
sym-keybits: 128
x: e71805c1fdbd36b2f0493b6b6c1eb56493e7237273bbdfa9d15993a16a04b644
y: 5a4f2dc1b2916bbc6938b22008839b280cbe8a1de8e9a5ea3ac0264c6157ee29
我是按照官网的这个安装教程:
https://tpm2-tools.readthedocs.io/en/stable/INSTALL/
如下:
不知道跟您说的安装方式一样吗?
我指的是 TPM 模拟器 libtms:
https://github.com/stefanberger/libtpms
我安装了这个libtms,需要怎么启动这个模拟器呢,然后怎么通过tpm2-tss、tpm2-tools、tpm2-abrmd连接这个模拟器呢
您可以在以下位置了解如何将 libtpms 与 swtpm 结合使用:
https://github.com/stefenberger/swtpm/wiki
TCTI 接口记录在:
https://github.com/tpm2-software/tpm2-tss/blob/master/doc/tcti.md
TCTI 也可以直接与“conf=libtpms:tpm_state”一起使用。
但是,此处必须执行 tpm 启动来初始化 tpm_state 文件。
非常感谢,我按您说的研究下