-
Notifications
You must be signed in to change notification settings - Fork 45
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Unable to unlock root partition with tpm2 key #233
Comments
Thanks for reporting it. Is it a regression from 0.10 booster version? Also how did you enroll your your systemd-tpm2 partition? What parameters did you use? And what version of systemd do you have? |
Not sure about regression from 0.10, I just give a try for booster. But I can try to downgrade and report result later if you wish. |
The same issue with booster 0.10 |
Bisecting points me to c1b6667 My assumption as tpm modules are built-in into the kernel in archlinux packages, booster doesn't stand a chance to capture associated udev event as tpm devices initialized even before booster enters it's main method. So we should check presence of /dev/tpmrm0 and don't use waiters if tpm already here. Something like that: --- a/init/udev.go
+++ b/init/udev.go
@@ -2,6 +2,9 @@ package main
import (
"fmt"
+ "github.com/google/go-tpm/legacy/tpm2"
+ "io"
+ "net"
"os"
"path/filepath"
"regexp"
@@ -73,8 +76,19 @@ var (
)
func udevListener() error {
- // Initialize tpmReadyWg
- tpmReadyWg.Add(1)
+ var dev io.ReadWriteCloser
+
+ if enableSwEmulator {
+ dev, _ = net.Dial("tcp", ":2321") // swtpm emulator is listening at port 2321
+ } else {
+ dev, _ = tpm2.OpenTPM("/dev/tpmrm0")
+ }
+ if dev != nil {
+ dev.Close()
+ } else {
+ // Initialize tpmReadyWg
+ tpmReadyWg.Add(1)
+ }
udevConn = new(netlink.UEventConn)
if err := udevConn.Connect(netlink.KernelEvent); err != nil { It fixes |
I believe I found the cause: systemd/systemd@d9b5841 Since systemd 252 systemd-cryptenroll generates tpm2 pins with |
I think it is better to check the file existence at Line 54 in 30d1a2e
|
Is this issue being worked on by someone? dracut handles the new systemd-cryptenroll setup just fine, FYI. |
I don't know about anatol but I only skimmed through the relevant code because I was also interested in getting tpm2 unlocking to work. But this doesn't appear to be a simple fix For tpm2 unlocking, rather than systemd, users can use the Clevis functionality in Booster. I believe this should be fine as it doesn't use the same code path as systemd-tpm2. Or you can just use mkinitcpio or dracut. For mkinitcpio, just be sure to configure it with the relevant hooks. |
has this been solved yet? |
I see that systemd-cryptsenroll tool adds a new field named Here is the systemd code to reconstruct SRK handle from the data: r = tpm2_handle_new(c, &primary);
if (r < 0)
return r;
primary->keep = true;
log_debug("Found existing SRK key to use, deserializing ESYS_TR");
rc = sym_Esys_TR_Deserialize(
c->esys_context,
srk_buf,
srk_buf_size,
&primary->esys_handle);
if (rc != TSS2_RC_SUCCESS)
return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
"Failed to deserialize primary key: %s", sym_Tss2_RC_Decode(rc)); And booster needs to do it using cc @chrisfenner @Foxboron who recently worked with go-tpm if they know the answer to this question. |
You could try |
Booster still uses the legacy go-tpm API https://github.com/anatol/booster/blob/master/init/tpm.go @chrisfenner Is there a way to perform |
The bad news is that in the legacy API, per-type unmarshalling support is more spotty. It might be there somewhere depending on what you want to unmarshal. The good news is you don't have to switch all your code to the new API :) you could update the version of go-tpm to 0.9.0 and import github.com/google/go-tpm/legacy/tpm2 everywhere you were importing tpm2 before. Then, in the code that wants to call the new API, you can use github.com/google/go-tpm/tpm2. |
Thank you @chrisfenner I will try to mix the APIs So I looked at the tpm-tss code and TSS2_RC
iesys_MU_IESYS_RESOURCE_Unmarshal(
const uint8_t *buffer,
size_t size,
size_t *offset,
IESYS_RESOURCE *dst)
{
LOG_TRACE("called: buffer=%p size=%zu offset=%p dst=%p",
buffer, size, offset, dst);
if (buffer == NULL) {
LOG_ERROR("buffer=NULL");
return TSS2_ESYS_RC_BAD_REFERENCE;
}
TSS2_RC ret;
size_t offset_loc = (offset != NULL)? *offset : 0;
if (dst != NULL)
memset(dst, 0, sizeof(*dst));
TPM2_HANDLE out_handle;
ret = Tss2_MU_TPM2_HANDLE_Unmarshal(buffer, size, &offset_loc,
(dst == NULL)? &out_handle : &dst->handle);
return_if_error(ret, "Error unmarshaling subfield handle");
ret = Tss2_MU_TPM2B_NAME_Unmarshal(buffer, size, &offset_loc,
(dst == NULL)? NULL : &dst->name);
return_if_error(ret, "Error unmarshaling subfield name");
IESYSC_RESOURCE_TYPE out_rsrcType;
ret = iesys_MU_IESYSC_RESOURCE_TYPE_Unmarshal(buffer, size, &offset_loc,
(dst == NULL)? &out_rsrcType : &dst->rsrcType);
return_if_error(ret, "Error unmarshaling subfield rsrcType");
ret = iesys_MU_IESYS_RSRC_UNION_Unmarshal(buffer, size, &offset_loc,
(dst == NULL)? out_rsrcType : dst->rsrcType,
(dst == NULL)? NULL : &dst->misc);
return_if_error(ret, "Error unmarshaling subfield misc");
if (offset != NULL)
*offset = offset_loc;
return TSS2_RC_SUCCESS;
} What go-tpm type would correspond to |
Hmm, |
https://github.com/siderolabs/talos/blob/main/internal/pkg/encryption/keys/tpm2.go |
@anatol same issue here. any ideas how to workaround it? thanks. |
booster 0.11, both with and without universal:true.
Dmesg and luksdump
Main part of the log is
Not sure why booster doesn't see tpm2, dracut works just fine with this setup.
The text was updated successfully, but these errors were encountered: