I am trying to find a way to use a TPM to sign data using the private endorsement key (EK).
Using the samples from the TSS.MSR library in C#, I was able to assemble a small program:
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;
}
The program connects a TPM simulator, makes sure the EK is created and then, asks the TPM to sign data using the Endorsement Key. It fails with the following error:
Tpm2Lib.TpmException: 'Error {AuthUnavailable} was returned for command Sign.
Details:
[Code=TpmRc.AuthUnavailable],
[RawCode=0x12F,303]
[ErrorEntity=Unknown],
[ParmNum=0]
[ParmName=Unknown]'
Question
Can the EK be used to sign data and, if yes, what do I have to do to make it work?
EK cannot be used to sign data. Only thing EK can pretty much be used for is for AIK enrollment.
Not sure about your use case. But if you are planning to use signing by EK as a proof of identity, you can instead use AIK for that.