我正在尝试找到一种使用 TPM 使用私有背书密钥 (EK) 对数据进行签名的方法。
使用C# 中TSS.MSR库中的示例,我能够组装一个小程序:
private void ConnectTpmAndSign()
{
// ************************************************************
// Initializes the simulated TPM.
// ************************************************************
const string DefaultSimulatorName = "127.0.0.1";
const int DefaultSimulatorPort = 2321;
var tpmDevice = new TcpTpmDevice(DefaultSimulatorName, DefaultSimulatorPort);
tpmDevice.Connect();
var tpm = new Tpm2(tpmDevice);
tpmDevice.PowerCycle();
tpm.Startup(Su.Clear);
// ****************************************************
// Extracts the public portion of the Endorsement key.
// *****************************************************
var handleEK = new TpmHandle(0x81010001);
TpmPublic EKpub = tpm._AllowErrors().ReadPublic(handleEK, out byte[] _, out byte[] _);
if (!tpm._LastCommandSucceeded())
EKpub = CreateEndorsementKey(tpm, handleEK);
// *********************************************************
// Signs the data with the TPM
// **********************************************************
byte[] dataToSign = new byte[] { 0x01, 0x02, 0x03 };
// --> Fails here <--
var signature = tpm.Sign(handleEK, dataToSign, new SigSchemeRsassa(), TpmHashCheck.Null()) as SignatureRsassa;
...
}
private static TpmPublic CreateEndorsementKey(Tpm2 tpm2, TpmHandle tpmHandle)
{
TpmHandle primary = tpm2.CreatePrimary(
new TpmHandle(TpmHandle.RhEndorsement),
new SensitiveCreate(/*SecretPin, null*/),
new TpmPublic(TpmAlgId.Sha256, ObjectAttr.FixedTPM | ObjectAttr.FixedParent | ObjectAttr.SensitiveDataOrigin | ObjectAttr.AdminWithPolicy | ObjectAttr.Restricted | ObjectAttr.Decrypt, new byte[32]
{
(byte) 131,
(byte) 113,
(byte) 151,
(byte) 103,
(byte) 68,
(byte) 132,
(byte) 179,
(byte) 248,
(byte) 26,
(byte) 144,
(byte) 204,
(byte) 141,
(byte) 70,
(byte) 165,
(byte) 215,
(byte) 36,
(byte) 253,
(byte) 82,
(byte) 215,
(byte) 110,
(byte) 6,
(byte) 82,
(byte) 11,
(byte) 100,
(byte) 242,
(byte) 161,
(byte) 218,
(byte) 27,
(byte) 51,
(byte) 20,
(byte) 105,
(byte) 170
}, (IPublicParmsUnion)new RsaParms(new SymDefObject(TpmAlgId.Aes, (ushort)128, TpmAlgId.Cfb), (IAsymSchemeUnion)new NullAsymScheme(), (ushort)2048, 0U), (IPublicIdUnion)new Tpm2bPublicKeyRsa(new byte[256])), Array.Empty<byte>(), Array.Empty<PcrSelection>(), out TpmPublic tpmPublic, out _, out _, out _);
tpm2.EvictControl(TpmHandle.RhOwner, primary, tpmHandle);
tpm2.FlushContext(primary);
return tpmPublic;
}
该程序连接 TPM 模拟器,确保创建 EK,然后要求 TPM 使用背书密钥对数据进行签名。它失败并出现以下错误:
Tpm2Lib.TpmException: 'Error {AuthUnavailable} was returned for command Sign.
Details:
[Code=TpmRc.AuthUnavailable],
[RawCode=0x12F,303]
[ErrorEntity=Unknown],
[ParmNum=0]
[ParmName=Unknown]'
问题
EK 可以用来签署数据吗?如果可以,我需要做些什么才能让它发挥作用?