diff --git a/go.mod b/go.mod index d3bea7f..9da43e7 100644 --- a/go.mod +++ b/go.mod @@ -31,6 +31,8 @@ require ( gopkg.in/yaml.v3 v3.0.1 ) +require github.com/google/go-tpm v0.9.0 + require ( atomicgo.dev/cursor v0.1.3 // indirect atomicgo.dev/keyboard v0.2.9 // indirect diff --git a/go.sum b/go.sum index 726bc14..0643bcd 100644 --- a/go.sum +++ b/go.sum @@ -260,6 +260,8 @@ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-containerregistry v0.15.2 h1:MMkSh+tjSdnmJZO7ljvEqV1DjfekB6VUEAZgy3a+TQE= github.com/google/go-containerregistry v0.15.2/go.mod h1:wWK+LnOv4jXMM23IT/F1wdYftGWGr47Is8CG+pmHK1Q= +github.com/google/go-tpm v0.9.0 h1:sQF6YqWMi+SCXpsmS3fd21oPy/vSddwZry4JnmltHVk= +github.com/google/go-tpm v0.9.0/go.mod h1:FkNVkc6C+IsvDI9Jw1OveJmxGZUUaKxtrpOS47QWKfU= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= diff --git a/internal/constants/constants.go b/internal/constants/constants.go index 9720a73..baa0424 100644 --- a/internal/constants/constants.go +++ b/internal/constants/constants.go @@ -108,4 +108,5 @@ const ( LogDir = "/run/immucore" PathAppend = "/usr/bin:/usr/sbin:/bin:/sbin" PATH = "PATH" + DefaultPCR = 11 ) diff --git a/internal/utils/common.go b/internal/utils/common.go index 99a45be..7bc9529 100644 --- a/internal/utils/common.go +++ b/internal/utils/common.go @@ -1,6 +1,7 @@ package utils import ( + "crypto/sha256" "errors" "fmt" "os" @@ -11,6 +12,8 @@ import ( "time" "github.com/avast/retry-go" + "github.com/google/go-tpm/tpm2" + "github.com/google/go-tpm/tpm2/transport" "github.com/joho/godotenv" "github.com/kairos-io/immucore/internal/constants" "github.com/kairos-io/kairos-sdk/state" @@ -263,3 +266,35 @@ func DropToEmergencyShell() { } } } + +// PCRExtend extends the given pcr with the give data. +func PCRExtend(pcr int, data []byte) error { + t, err := transport.OpenTPM() + if err != nil { + return err + } + defer func(t transport.TPMCloser) { + _ = t.Close() + }(t) + digest := sha256.Sum256(data) + pcrHandle := tpm2.PCRExtend{ + PCRHandle: tpm2.AuthHandle{ + Handle: tpm2.TPMHandle(pcr), + Auth: tpm2.PasswordAuth(nil), + }, + Digests: tpm2.TPMLDigestValues{ + Digests: []tpm2.TPMTHA{ + { + HashAlg: tpm2.TPMAlgSHA256, + Digest: digest[:], + }, + }, + }, + } + + if _, err = pcrHandle.Execute(t); err != nil { + return err + } + + return nil +} diff --git a/pkg/state/steps_uki.go b/pkg/state/steps_uki.go index db5d0ec..33aee4e 100644 --- a/pkg/state/steps_uki.go +++ b/pkg/state/steps_uki.go @@ -23,16 +23,9 @@ import ( ) // UKIExtendPCR extends the PCR with the given extension in a graceful way. -func UKIExtendPCR(extension string) (string, error) { - if _, err := os.Stat("/usr/lib/systemd/systemd-pcrphase"); err == nil { - return internalUtils.CommandWithPath(fmt.Sprintf("/usr/lib/systemd/systemd-pcrphase --graceful %s", extension)) - } +func UKIExtendPCR(extension string) error { + return internalUtils.PCRExtend(cnst.DefaultPCR, []byte(extension)) - if _, err := os.Stat("/usr/lib/systemd/systemd-pcrextend"); err == nil { - return internalUtils.CommandWithPath(fmt.Sprintf("/usr/lib/systemd/systemd-pcrextend --graceful %s", extension)) - } - - return "", fmt.Errorf("no systemd-pcrphase or systemd-pcrextend found") } // UKIMountBaseSystem mounts the base system for the UKI boot system @@ -304,10 +297,9 @@ func (s *State) UkiPivotToSysroot(g *herd.Graph) error { } ext := "enter-initrd" - output, pcrErr := UKIExtendPCR(ext) + pcrErr := UKIExtendPCR(ext) if pcrErr != nil { - internalUtils.Log.Err(pcrErr).Msg("running systemd-pcrextends") - internalUtils.Log.Debug().Str("ext", ext).Str("out", output).Msg("systemd-pcrextends") + internalUtils.Log.Err(pcrErr).Str("ext", ext).Msg("extend-pcr") } pcrErr = os.MkdirAll("/run/systemd", 0755) // #nosec G301 -- Original dir has this permissions @@ -492,10 +484,9 @@ func (s *State) UKIBootInitDagStep(g *herd.Graph) error { var err error ext := "leave-initrd" - output, err := UKIExtendPCR(ext) + err = UKIExtendPCR(ext) if err != nil { - internalUtils.Log.Err(err).Msg("running systemd-pcrextends") - internalUtils.Log.Debug().Str("ext", ext).Str("out", output).Msg("systemd-pcrextends") + internalUtils.Log.Err(err).Str("ext", ext).Msg("extend-pcr") internalUtils.DropToEmergencyShell() }