Skip to content

Conversation

@cmatsuoka
Copy link
Contributor

Execute TPM provisioning on install using Chris Coulson's FDE utils code
from https://github.com/chrisccoulson/ubuntu-core-fde-utils. This also
requires google/go-tpm#109 which has been added
to vendored packages.

Try to provision the TPM as late as possible to prevent a situation
where the installation fails after the TPM is provisioned. Provisioning
happens just before sealing the LUKS device keyfile and the lockout
authorization value is stored inside the encrypted partition.

Signed-off-by: Claudio Matsuoka [email protected]

Execute TPM provisioning on install using Chris Coulson's FDE utils code
from https://github.com/chrisccoulson/ubuntu-core-fde-utils. This also
requires google/go-tpm#109 which has been added
to vendored packages.

Try to provision the TPM as late as possible to prevent a situation
where the installation fails after the TPM is provisioned. Provisioning
happens just before sealing the LUKS device keyfile and the lockout
authorization value is stored inside the encrypted partition.

Signed-off-by: Claudio Matsuoka <[email protected]>
Copy link
Contributor

@zyga zyga left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Quick pass of my uninformed eyes. I didn't review any of the TPM mechanics but I left a lot of little wording nitpicks for error messages and some misc comments.

)

const (
srkHandle tpmutil.Handle = 0x81000000
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be great to reference this to some documentation.

func ProvisionTPM(lockoutAuth []byte) error {
rw, err := tpm2.OpenTPM(tpmPath)
if err != nil {
return fmt.Errorf("failed to open TPM device: %v", err)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Small wording tweak to the error message.

Suggested change
return fmt.Errorf("failed to open TPM device: %v", err)
return fmt.Errorf("cannot to open TPM device %q: %v", tpmPath, err)


c, _, err := tpm2.GetCapability(rw, tpm2.CapabilityTPMProperties, 1, permanentProps)
if err != nil {
return fmt.Errorf("failed to request permanent properties: %v", err)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return fmt.Errorf("failed to request permanent properties: %v", err)
return fmt.Errorf("cannot request permanent TPM properties: %v", err)

}

if err := tpm2.Clear(rw, tpm2.HandleLockout, ""); err != nil {
return fmt.Errorf("failed to clear the TPM: %v", err)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return fmt.Errorf("failed to clear the TPM: %v", err)
return fmt.Errorf("cannot clear the TPM: %v", err)

func RequestTPMClearUsingPPI() error {
f, err := os.OpenFile(ppiPath, os.O_WRONLY, 0)
if err != nil {
return fmt.Errorf("failed to open request handle: %v", err)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return fmt.Errorf("failed to open request handle: %v", err)
return fmt.Errorf("cannot open TPM request handle %q: %v", ppiPath, err)

defer f.Close()

if _, err := f.WriteString(clearPPIRequest); err != nil {
return fmt.Errorf("failed to submit request: %v", err)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return fmt.Errorf("failed to submit request: %v", err)
return fmt.Errorf("cannot submit TPM request: %v", err)

func createWritable(keyfile string, keyfileSize int, cryptdev string) error {
logger.Noticef("Creating new writable")
func createWritable(keyBuffer []byte, cryptdev string) error {
logger.Noticef("Creating new ubuntu-data")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
logger.Noticef("Creating new ubuntu-data")
logger.Noticef("Creating new ubuntu-data partition")

It would be good to always refer to partitions as "foo" partition, because the bare name like ubuntu-data is not associated with partitions in any way.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.


// Don't remove this sync, it prevents file corruption on vfat
if err := exec.Command("sync").Run(); err != nil {
return fmt.Errorf("cannot sync: %s", err)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please just use syscall.Sync instead. No need to fork for this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, excellent, that's much better, thank you.

Copy link
Contributor

@mvo5 mvo5 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, I pushed a small tweak to the vendor.json and a small suggestion in the code.

const (
srkHandle tpmutil.Handle = 0x81000000

tpmPath string = "/dev/tpm0"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need the "string" here (does not cause harm either though).

"origin": "github.com/chrisccoulson/go-tpm",
"path": "github.com/google/go-tpm",
"revision": "c6c7cb7465ae50e13263f2f8ff33f57d1f9859bc",
"revisionTime": "2019-07-08T13:36:22Z"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will need the following extra line:

"tree": true

return nil
}

func RequestTPMClearUsingPPI() error {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is used only inside this package, it should probably be unexported - we can always export it if needed.

@@ -0,0 +1,100 @@
package fdeutils
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copyright header missing.

@mvo5
Copy link
Contributor

mvo5 commented Jul 10, 2019

I talked to Chris and he preferes to have the code in his repo for now. I will rework this to import it from his repo.

@mvo5 mvo5 merged commit 073180b into canonical:uc20 Jul 12, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants