Closed svundru closed 4 years ago
Sorry for the late response.
First and foremost, check your U-Boot commit. In July 2020, the TPM TIS driver compatible changed, breaking all custom device trees using the TPM, including this one. The compatible changed from tis,tpm2-spi
to tcg,tpm_tis-spi
.
Thus, if your U-Boot is newer than July 2020, you have to change the compatible in the device tree. Adding tcg,tpm_tis-spi
should suffice.
If that does not solve your problem, you can increase the log level in the U-Boot configuration menu (make menuconfig
). If you need, write the output into a file. To catch driver issues, search for tpm
and look out for the compatible. Basically, U-Boot looks at the device tree (loaded by the closed-source Raspberry Pi bootloader). When it sees the compatible, it searches for drivers with the same compatible and loads them.
If you cannot find the compatible in your logging output, maybe the Raspberry Pi bootloader is not loading your device tree overlay (tpm-soft-spi.dtbo
). In this case, check if you added the correct lines to /boot/config.txt
.
Thank you for reporting this issue. I have fixed it in 3d256c604. Please let me know if that fixed your problem.
Thanks for the response. I did this change after few trail and error and it is working for me now. I have another question, I am planning to add TPM2SetPrimaryPolicy() command to my uboot, this is not part of default u-boot. This command needs a auth session. Do you have any idea if someone on u-boot already working on these commands or is there a development brnach with these commands implemented on u-boot?
Also how do this soft spi driver from ST micro TPM2?
To my knowledge there is no official support. However, you are lucky, I have a patch lying around because I needed this command myself. I did not have the time to upstream it, yet. I added a patch at the end. I hope this compiles, as I did not test it.
What do you mean by your second question?
diff --git a/cmd/tpm-v2.c b/cmd/tpm-v2.c
index e6742656f5..658ad48f3e 100644
--- a/cmd/tpm-v2.c
+++ b/cmd/tpm-v2.c
@@ -354,6 +354,55 @@ static int do_tpm_pcr_setauthvalue(struct cmd_tbl *cmdtp, int flag,
key, key_sz));
}
+static int do_tpm2_setprimarypolicy(struct cmd_tbl *cmdtp, int flag,
+ int argc, char * const argv[])
+{
+ u32 handle;
+ void *auth_policy = map_sysmem(simple_strtoul(argv[2], NULL, 0), 0);
+ const char *pw = (argc == 3) ? NULL : argv[3];
+ const ssize_t pw_sz = pw ? strlen(pw) : 0;
+ struct udevice *dev;
+ int ret;
+ u32 rc;
+
+ ret = get_tpm(&dev);
+ if (ret) {
+ rc = ret;
+ goto unmap_auth_policy;
+ }
+
+ if (argc < 3 || argc > 4) {
+ rc = CMD_RET_USAGE;
+ goto unmap_auth_policy;
+ }
+
+ if (pw_sz > TPM2_DIGEST_LEN) {
+ rc = -EINVAL;
+ goto unmap_auth_policy;
+ }
+
+ if (!strcasecmp("TPM2_RH_LOCKOUT", argv[1]))
+ handle = TPM2_RH_LOCKOUT;
+ else if (!strcasecmp("TPM2_RH_ENDORSEMENT", argv[1]))
+ handle = TPM2_RH_ENDORSEMENT;
+ else if (!strcasecmp("TPM2_RH_OWNER", argv[1]))
+ handle = TPM2_RH_OWNER;
+ else if (!strcasecmp("TPM2_RH_PLATFORM", argv[1]))
+ handle = TPM2_RH_PLATFORM;
+ else {
+ rc = CMD_RET_USAGE;
+ goto unmap_auth_policy;
+ }
+
+unmap_auth_policy:
+ unmap_sysmem(auth_policy);
+
+ return report_return_code(tpm2_setprimarypolicy(dev, pw, pw_sz, handle,
+ auth_policy));
+}
+
static struct cmd_tbl tpm2_commands[] = {
U_BOOT_CMD_MKENT(device, 0, 1, do_tpm_device, "", ""),
U_BOOT_CMD_MKENT(info, 0, 1, do_tpm_info, "", ""),
@@ -367,6 +416,8 @@ static struct cmd_tbl tpm2_commands[] = {
U_BOOT_CMD_MKENT(dam_reset, 0, 1, do_tpm_dam_reset, "", ""),
U_BOOT_CMD_MKENT(dam_parameters, 0, 1, do_tpm_dam_parameters, "", ""),
U_BOOT_CMD_MKENT(change_auth, 0, 1, do_tpm_change_auth, "", ""),
+ U_BOOT_CMD_MKENT(setprimarypolicy, 0, 1,
+ do_tpm2_setprimarypolicy, "", ""),
U_BOOT_CMD_MKENT(pcr_setauthpolicy, 0, 1,
do_tpm_pcr_setauthpolicy, "", ""),
U_BOOT_CMD_MKENT(pcr_setauthvalue, 0, 1,
@@ -435,6 +486,10 @@ U_BOOT_CMD(tpm2, CONFIG_SYS_MAXARGS, 1, do_tpm, "Issue a TPMv2.x command",
" <hierarchy>: the hierarchy\n"
" <new_pw>: new password for <hierarchy>\n"
" <old_pw>: optional previous password of <hierarchy>\n"
+"setprimarypolicy <hierarchy> <authpolicy_addr> [<password>]\n"
+" <hierarchy>: handle to the hierarchy\n"
+" <authpolicy_addr>: memory address to a 32-byte SHA256 authPolicy digest\n"
+" <password>: optional password of <hierarchy>\n"
"pcr_setauthpolicy|pcr_setauthvalue <pcr> <key> [<password>]\n"
" Change the <key> to access PCR #<pcr>.\n"
" hierarchy and may be empty.\n"
diff --git a/include/tpm-v2.h b/include/tpm-v2.h
index d53d2e4023..ef2b15d0f4 100644
--- a/include/tpm-v2.h
+++ b/include/tpm-v2.h
@@ -339,4 +339,20 @@ u32 tpm2_pcr_setauthvalue(struct udevice *dev, const char *pw,
const ssize_t pw_sz, u32 index, const char *key,
const ssize_t key_sz);
+/**
+/**
+ * Issue a TPM_SetPrimaryPolicy command.
+ *
+ * @dev TPM device
+ * @pw Password
+ * @pw_sz Length of the password
+ * @auth_handle Handle of the entity whose authPolicy is to be set
+ * @auth_policy New authPolicy digest
+ *
+ * @return code of the operation
+ */
+u32 tpm2_setprimarypolicy(struct udevice *dev, const char *pw,
+ const ssize_t pw_sz, u32 auth_handle,
+ const uint8_t *auth_policy);
+
#endif /* __TPM_V2_H */
diff --git a/lib/tpm-v2.c b/lib/tpm-v2.c
index 5a039f65d1..e76df55026 100644
--- a/lib/tpm-v2.c
+++ b/lib/tpm-v2.c
@@ -422,3 +422,50 @@ u32 tpm2_pcr_setauthvalue(struct udevice *dev, const char *pw,
return tpm_sendrecv_command(dev, command_v2, NULL, NULL);
}
+
+u32 tpm2_setprimarypolicy(struct udevice *dev, const char *pw,
+ const ssize_t pw_sz, u32 auth_handle,
+ const uint8_t *auth_policy)
+{
+ u8 command_v2[COMMAND_BUFFER_SIZE] = {
+ tpm_u16(TPM2_ST_SESSIONS), /* TAG */
+ tpm_u32(63 + pw_sz), /* Length */
+ tpm_u32(TPM2_CC_SETPRIMARYPOLICY), /* Command code */
+
+ /* HANDLE */
+ tpm_u32(auth_handle), /* authHandle */
+
+ /* AUTH_SESSION */
+ tpm_u32(9 + pw_sz), /* Authorization size */
+ tpm_u32(TPM2_RS_PW), /* session handle */
+ tpm_u16(0), /* Size of <nonce> */
+ /* <nonce> (if any) */
+ 0, /* Attributes: Cont/Excl/Rst */
+ tpm_u16(pw_sz), /* Size of <hmac/password> */
+ /* STRING(pw) <hmac/password> (if any) */
+
+ /* TPM2B_DIGEST authPolicy */
+ /* tpm_u16(TPM2_ALG_SHA256) hashAlg */
+ };
+ unsigned int offset = 27;
+ int ret;
+
+ /*
+ * Fill the command structure starting from the first buffer:
+ * - the password (if any)
+ * - the timeout in seconds
+ */
+ ret = pack_byte_string(command_v2, sizeof(command_v2), "swsw",
+ offset, pw, pw_sz,
+ offset + pw_sz, TPM2_DIGEST_LEN,
+ offset + pw_sz + sizeof(u16), auth_policy,
+ TPM2_DIGEST_LEN,
+ offset + pw_sz + sizeof(u16) + TPM2_DIGEST_LEN,
+ TPM2_ALG_SHA256);
+ offset += pw_sz + sizeof(u16) + TPM2_DIGEST_LEN + sizeof(u16);
+
+ if (ret)
+ return TPM_LIB_ERROR;
+
+ return tpm_sendrecv_command(dev, command_v2, NULL, NULL);
+}
Thanks for the quick response. I will integrate this and let you know how it goes.
Regarding my second question, I tried the following device tree change on infineion TPM2 and that worked for me. I need to make the ST micro TPM2 chip work on uboot with my raspbery pi. what changes I need to make to device tree and soft spi driver code to make it work on ST Micro TPM2 ? compatible = "infineon,slb9670", "tis,tpm2-spi", "tcg,tpm_tis-spi"; devuce
As long as your TPM uses SPI, it should probably work you. I have tested this with an Infineon SLB9670 only.
Thanks, I will try on ST micro TPM2.
I see the following compilation error:
CC cmd/tpm-v2.o
cmd/tpm-v2.c: In function ‘do_tpm2_setprimarypolicy’:
cmd/tpm-v2.c:393:12: error: ‘TPM2_RH_ACT0’ undeclared (first use in this function); did you mean ‘TPM2_RC_FMT1’?
handle = TPM2_RH_ACT0;
^~~~
TPM2_RC_FMT1
cmd/tpm-v2.c:393:12: note: each undeclared identifier is reported only once for each function it appears in
scripts/Makefile.build:265: recipe for target 'cmd/tpm-v2.o' failed
make[1]: [cmd/tpm-v2.o] Error 1
Makefile:1780: recipe for target 'cmd' failed
make: [cmd] Error 2
I see, my bad. I edited the patch. Should be fixed now. You can simply remove the case
for the act.
thx, I see more compile errors:
CC lib/tpm-v2.o In file included from lib/tpm-v2.c:12:0: lib/tpm-v2.c: In function ‘tpm2_setprimarypolicy’: lib/tpm-v2.c:477:11: error: ‘TPM2_CC_SETPRIMARYPOLICY’ undeclared (first use in this function); did you mean ‘TPM2_CC_GET_CAPABILITY’? tpm_u32(TPM2_CC_SETPRIMARYPOLICY), / Command code / ^ lib/tpm-utils.h:16:20: note: in definition of macro ‘__MSB’
^
lib/tpm-utils.h:19:20: note: in expansion of macro ‘tpm_u16’
^~~~~~~
lib/tpm-v2.c:477:3: note: in expansion of macro ‘tpm_u32’
tpm_u32(TPM2_CC_SETPRIMARYPOLICY), / Command code /
^~~
lib/tpm-v2.c:477:11: note: each undeclared identifier is reported only once for each function it appears in
tpm_u32(TPM2_CC_SETPRIMARYPOLICY), / Command code /
^
lib/tpm-utils.h:16:20: note: in definition of macro ‘__MSB’
^
lib/tpm-utils.h:19:20: note: in expansion of macro ‘tpm_u16’
^~~~~~~
lib/tpm-v2.c:477:3: note: in expansion of macro ‘tpm_u32’
tpm_u32(TPM2_CC_SETPRIMARYPOLICY), / Command code /
^~~
scripts/Makefile.build:265: recipe for target 'lib/tpm-v2.o' failed
make[1]: [lib/tpm-v2.o] Error 1
Makefile:1780: recipe for target 'lib' failed
make: [lib] Error 2
it compiles with this diff: --- a/include/tpm-v2.h +++ b/include/tpm-v2.h @@ -82,6 +82,7 @@ enum tpm2_command_codes { TPM2_CC_CLEARCONTROL = 0x0127, TPM2_CC_CLEARCONTROL = 0x0127, TPM2_CC_HIERCHANGEAUTH = 0x0129, TPM2_CC_PCR_SETAUTHPOL = 0x012C,
Nice, I hope I could help. Closing this issue.
what does it takes to make these instructions work on Raspberry pi model 3 with infenion TPM2?
Should be the same. I tested this with an Infineon SLB9670, so the only variable would be the Raspberry Pi 3. You should be able to use 64-bit software there, as well.
Ok, thanks. I will work on RPI3 to see if it works for me.
I tried these instructions(https://github.com/joholl/rpi4-uboot-tpm ) on raspberry pi 4. tpm2 init gives me error message "Could not set TPM 0 (rc = 1). any pointers would be appreciated.