Closed danielwangksu closed 2 years ago
The call below teaches ESYS, "hey, when you need the owner auth use this".
Esys_TR_SetAuth(ectx, ESYS_TR_RH_OWNER, &hieararchy_auth );
But here you never set the password:
TPM2B_AUTH hieararchy_auth = { 0 };
The struct has a size and buffer field. You need to set buffer to the password and update the size field.
const char password[] = "5AtOuyKBA/UsW1xrqAwjxfSA1nM=";
TPM2B_AUTH hieararchy_auth = {
.size = sizeof(password) - sizeof(char)
};
memcpy(hieararchy_auth.buffer, password, hieararchy_auth.size);
I usually roll that into a setpassword function since it gets used a lot, here is a sample:
static TSS2_RC set_password(ESYS_CONTEXT *ectx, ESYS_TR handle, const char *password)
{
TPM2B_AUTH auth = { 0 };
if (strlen(password) > sizeof(auth.buffer)) {
// todo make better error
return 1;
}
auth.size = strlen(password);
memcpy(auth.buffer, password, auth.size);
return Esys_TR_SetAuth(ectx, handle, &auth);
}
int main(int argc, char *argv[]) {
ESYS_CONTEXT *ectx = NULL;
Esys_Initialize(&ectx, NULL, NULL);
return set_password(ectx, ESYS_TR_RH_OWNER, "5AtOuyKBA/UsW1xrqAwjxfSA1nM=");
}
Thank you so much @williamcroberts this saved my day! I was down in the robbit hole trying to explore Esys_StartAuthSession
and Esys_TRSess_SetAttributes
to somehow pass the password!
Sorry, maybe I missed anything. I tested the above solution works on Linux but on Windows I got the following error:
WARNING:esys:api\Esys_CreatePrimary.c:400:Esys_CreatePrimary_Finish() Received TPM Error
ERROR:esys:api\Esys_CreatePrimary.c:135:Esys_CreatePrimary() Esys Finish ErrorCode (0x000000a2)
Esys_CreatePrimary: tpm:handle(unk):authorization failure without DA implications:
Any further suggestions?
Sorry, maybe I missed anything. I tested the above solution works on Linux but on Windows I got the following error:
WARNING:esys:api\Esys_CreatePrimary.c:400:Esys_CreatePrimary_Finish() Received TPM Error ERROR:esys:api\Esys_CreatePrimary.c:135:Esys_CreatePrimary() Esys Finish ErrorCode (0x000000a2) Esys_CreatePrimary: tpm:handle(unk):authorization failure without DA implications:
Any further suggestions? I think Windows sets the ownership password and so you may not be keying in the right password.
Perhaps the value that is getting stored into the registry isn't being setup in provision tpm call. Maybe try testing that the owner auth you're requesting was actually set to the TPM:
Set-TpmOwnerAuth -OwnerAuthorization "5AtOuyKBA/UsW1xrqAwjxfSA1nM=" -NewOwnerAuthorization "5AtOuyKBA/UsW1xrqAwjxfSA1nM="
See:
Thank you for all your help! It still has the same error. Here is what I did, and the return value (only showing the related fields):
Clear-Tpm
TpmPresent : True
TpmReady : False
...
OwnerAuth :
Import-TpmOwnerAuth -OwnerAuthorization "5AtOuyKBA/UsW1xrqAwjxfSA1nM="
TpmPresent : True
TpmReady : True
...
OwnerAuth : 5AtOuyKBA/UsW1xrqAwjxfSA1nM=
Set-TpmOwnerAuth -NewOwnerAuthorization "5AtOuyKBA/UsW1xrqAwjxfSA1nM="
TpmPresent : True
TpmReady : True
...
OwnerAuth :
I'm not sure why Import-TpmOwnerAuth
turns TpmReady
to True, and makes OwnerAuth
shows the value, but Set-TpmOwnerAuth
removes the OwnerAuth
value. But either way I'm using the same password value.
I also tried to run Set-TpmOwnerAuth -NewOwnerAuthorization "5AtOuyKBA/UsW1xrqAwjxfSA1nM="
the second time, but this time I got an error. After the first time, I had to use this command Set-TpmOwnerAuth -OwnerAuthorization "5AtOuyKBA/UsW1xrqAwjxfSA1nM=" -NewOwnerAuthorization "5AtOuyKBA/UsW1xrqAwjxfSA1nM="
. So I think the password should be set at this point, but the C program keep getting "tpm:handle(unk):authorization failure without DA implications"
Come back to report what I found. I thought maybe Windows 10 has some special session for taking ownership. So I cleaned TPM using PowerShell.
PS C:\WINDOWS\system32> Get-Tpm
TpmPresent : True
TpmReady : False
TpmEnabled : True
TpmActivated : True
TpmOwned : False
RestartPending : False
ManufacturerId : 1398033696
ManufacturerIdTxt : STM
ManufacturerVersion : 1.258.0.0
ManufacturerVersionFull20 : 1.258.0.0
ManagedAuthLevel : Delegated
OwnerAuth :
OwnerClearDisabled : False
AutoProvisioning : Enabled
LockedOut : False
LockoutHealTime : 2 hours
LockoutCount : 0
LockoutMax : 32
SelfTest : {}
In the C program I called the following functions:
ESYS_TR hierarchy = ESYS_TR_RH_OWNER;
TPM2B_AUTH hieararchy_auth = { 0 };
Esys_TR_SetAuth(ectx, hierarchy, &hieararchy_auth);
// take the ownership and setup an password I chose
Esys_HierarchyChangeAuth(ectx, hierarchy, ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE, new_auth);
TPM2B_PUBLIC pub_template = {
.size = 0,
.publicArea = {
.type = TPM2_ALG_ECC,
.nameAlg = TPM2_ALG_SHA256,
.objectAttributes = (TPMA_OBJECT_USERWITHAUTH |
TPMA_OBJECT_RESTRICTED |
TPMA_OBJECT_DECRYPT |
TPMA_OBJECT_FIXEDTPM |
TPMA_OBJECT_FIXEDPARENT |
TPMA_OBJECT_SENSITIVEDATAORIGIN),
.authPolicy = {
.size = 0,
},
.parameters.eccDetail = {
.symmetric = {
.algorithm = TPM2_ALG_AES,
.keyBits.aes = 128,
.mode.aes = TPM2_ALG_CFB,
},
.scheme = {
.scheme = TPM2_ALG_NULL,
},
.curveID = TPM2_ECC_NIST_P256,
.kdf = {
.scheme = TPM2_ALG_NULL,
.details = {}}
},
.unique.ecc = {
.x = {.size = 0,.buffer = {}},
.y = {.size = 0,.buffer = {}},
},
},
};
TPM2B_DATA outside_info = { 0 };
TPML_PCR_SELECTION pcrs = { 0 };
TPM2B_PUBLIC *out_pub = NULL;
TPM2B_CREATION_DATA *data = NULL;
TPM2B_DIGEST *hash = NULL;
TPMT_TK_CREATION *ticket = NULL;
// authorize the handle with the created password
Esys_TR_SetAuth(...);
Esys_CreatePrimary(ectx,
hierarchy,
ESYS_TR_PASSWORD,
ESYS_TR_NONE,
ESYS_TR_NONE,
&sens,
&pub_template,
&outside_info,
&pcrs,
&handle,
&out_pub,
&data,
&hash,
&ticket);
Esys_EvictControl(ectx,
hierarchy,
handle,
ESYS_TR_PASSWORD,
ESYS_TR_NONE,
ESYS_TR_NONE,
DEFAULT_SRK_HANDLE,
&new_handle);
This works on Linux with virtual TPM, but failed again on Windows, even there it shows TpmOwned: False
.
ERROR:esys:api\Esys_HierarchyChangeAuth.c:313:Esys_HierarchyChangeAuth_Finish() Received a non-TPM Error
ERROR:esys:api\Esys_HierarchyChangeAuth.c:114:Esys_HierarchyChangeAuth() Esys Finish ErrorCode (0x80280400)
Not sure why, maybe cooperate IT has special locks (I do not think so)? I guess Windows really do not want me to use TPM LOL.
Tried nothing but Esys_Clear(ectx, ESYS_TR_RH_LOCKOUT, ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE);
still get the same error:
ERROR:esys:api\Esys_Clear.c:295:Esys_Clear_Finish() Received a non-TPM Error
ERROR:esys:api\Esys_Clear.c:97:Esys_Clear() Esys Finish ErrorCode (0x80280400)
Error: Esys_Clear: 40:0x400:
Those are some weird error codes.... WTH is layer 40.
I would try the MS TSS (https://github.com/microsoft/TSS.MSR), just see if it bahves differently, then maybe we can figure out where the bug is. It would narrow it down to TPM or TSS.
Thank you @williamcroberts I tried TSS.MSR's TSS.CPP Samples.exe
before. "TSS.CPP Samples.exe" sys
gives me error:
TpmCppTester: Wrong response session tag
Exiting...
I will write a simply cpp to see what error got reported. But I'm not hopeful :(
I think Windows just does not allow us to use owner password. With tpm2-tss I was able to create primary key without specific auth value, it just when I try to make it persistent using EvictControl, it fails. The behavior is same using TSS.MSR, I can create primary key, but as soon as it reach EvictControl just abort. Same for calling tpm2-clear(). I'm trying to see if I can load primary key, and create signing key without auth on Windows.
I think Windows just does not allow us to use owner password. With tpm2-tss I was able to create primary key without specific auth value, it just when I try to make it persistent using EvictControl, it fails. The behavior is same using TSS.MSR, I can create primary key, but as soon as it reach EvictControl just abort. Same for calling tpm2-clear(). I'm trying to see if I can load primary key, and create signing key without auth on Windows.
Their resource manager, TBS, implements some command blocking, I wonder if you need to tweak that policy
Hi @williamcroberts indeed! Thank you for your response. Here is what I found through experiments on Windows 10. If I set TPM2B_AUTH
to all 0, I can create primary key, create/load signing key, etc. The only things you cannot do is Esys_Clear
and Esys_EvictControl
. This made me believe Windows has some kind of policies that control in TBS. I cannot make the primary key in persistent, but I guess I can live with this issue, as long as I can recreate primary key every reboot.
I understand in TPM as long as the parameters of creating primary keys are identical, the key would be identical. So my question is what exactly are those parameters? For example, if I use the following setup, can I assume the primary key is same every time the code is executed?
TPM2B_PUBLIC pub_template = {
.size = 0,
.publicArea = {
.type = TPM2_ALG_RSA,
.nameAlg = TPM2_ALG_SHA256,
.objectAttributes = (TPMA_OBJECT_FIXEDTPM |
TPMA_OBJECT_FIXEDPARENT |
TPMA_OBJECT_SENSITIVEDATAORIGIN |
TPMA_OBJECT_USERWITHAUTH |
TPMA_OBJECT_RESTRICTED |
TPMA_OBJECT_NODA |
TPMA_OBJECT_DECRYPT),
.authPolicy = {
.size = 0,
},
.parameters.rsaDetail = {
.symmetric = {
.algorithm = TPM2_ALG_AES,
.keyBits.aes = 128,
.mode.aes = TPM2_ALG_CFB,
},
.scheme = {
.scheme = TPM2_ALG_NULL,
.details = {}
},
.keyBits = 2048,
.exponent = 0,
},
},
};
...
Esys_CreatePrimary(...);
Hi @williamcroberts indeed! Thank you for your response. Here is what I found through experiments on Windows 10. If I set
TPM2B_AUTH
to all 0, I can create primary key, create/load signing key, etc. The only things you cannot do isEsys_Clear
andEsys_EvictControl
. This made me believe Windows has some kind of policies that control in TBS. I cannot make the primary key in persistent, but I guess I can live with this issue, as long as I can recreate primary key every reboot.I understand in TPM as long as the parameters of creating primary keys are identical, the key would be identical. So my question is what exactly are those parameters? For example, if I use the following setup, can I assume the primary key is same every time the code is executed?
Yep, exactly right.
Thank you @williamcroberts for your help! I'm closing this issues.
Hi all, I encountered an error using the EAPI on Windows 10. My simple goal is to create a primary key and load it into TPM at a fixed location -
0x81000001
and then create a keypair under the primary and leave the handle in a folder.Here is my setup for TPM using PowerShell (reference https://docs.microsoft.com/en-us/powershell/module/trustedplatformmodule/?view=windowsserver2022-ps):
After this the PowerShelel shows TPM is ready:
In my C code, it is simply trying to create a persistent primary
This is the error I got:
I guess I'm confused when and how to pass the OWNER password
"ownerauth"
. Any help is greatly appreciated! Thank you!