-
Notifications
You must be signed in to change notification settings - Fork 642
recovery: integrate TPM provisioning #7085
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
Changes from 1 commit
287d27f
f2ac2bf
8f2825c
316fb75
08c31d5
6e4b60d
7e796c9
1d70445
bc0c3db
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,100 @@ | ||||||
| package fdeutils | ||||||
|
||||||
|
|
||||||
| import ( | ||||||
| "errors" | ||||||
| "fmt" | ||||||
| "os" | ||||||
|
|
||||||
| "github.com/google/go-tpm/tpm2" | ||||||
| "github.com/google/go-tpm/tpmutil" | ||||||
| ) | ||||||
|
|
||||||
| const ( | ||||||
| srkHandle tpmutil.Handle = 0x81000000 | ||||||
|
||||||
|
|
||||||
| tpmPath string = "/dev/tpm0" | ||||||
|
||||||
| ppiPath string = "/sys/class/tpm/tpm0/ppi/request" | ||||||
|
|
||||||
| permanentProps uint32 = 0x00000200 | ||||||
| lockoutAuthSet uint32 = 1 << 2 | ||||||
| disableClear uint32 = 1 << 8 | ||||||
|
|
||||||
| clearPPIRequest string = "5" | ||||||
| ) | ||||||
|
|
||||||
| var ( | ||||||
| ErrClearRequiresPPI = errors.New("clearing requires the use of the Physical Presence Interface") | ||||||
|
|
||||||
| srkTemplate = tpm2.Public{ | ||||||
| Type: tpm2.AlgRSA, | ||||||
| NameAlg: tpm2.AlgSHA256, | ||||||
| Attributes: tpm2.FlagFixedTPM | tpm2.FlagFixedParent | tpm2.FlagSensitiveDataOrigin | | ||||||
| tpm2.FlagUserWithAuth | tpm2.FlagRestricted | tpm2.FlagDecrypt, | ||||||
| AuthPolicy: nil, | ||||||
| RSAParameters: &tpm2.RSAParams{ | ||||||
| Symmetric: &tpm2.SymScheme{ | ||||||
| Alg: tpm2.AlgAES, | ||||||
| KeyBits: 128, | ||||||
| Mode: tpm2.AlgCFB}, | ||||||
| KeyBits: 2048, | ||||||
| Exponent: 0, | ||||||
| ModulusRaw: make([]byte, 256)}} | ||||||
| ) | ||||||
|
|
||||||
| func ProvisionTPM(lockoutAuth []byte) error { | ||||||
| rw, err := tpm2.OpenTPM(tpmPath) | ||||||
| if err != nil { | ||||||
| return fmt.Errorf("failed to open TPM device: %v", err) | ||||||
|
||||||
| return fmt.Errorf("failed to open TPM device: %v", err) | |
| return fmt.Errorf("cannot to open TPM device %q: %v", tpmPath, err) |
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| return fmt.Errorf("failed to request permanent properties: %v", err) | |
| return fmt.Errorf("cannot request permanent TPM properties: %v", err) |
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| return fmt.Errorf("failed to clear the TPM: %v", err) | |
| return fmt.Errorf("cannot clear the TPM: %v", err) |
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| return fmt.Errorf("failed to create storage root key: %v", err) | |
| return fmt.Errorf("cannot create storage for TPM root key: %v", err) |
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| return fmt.Errorf("failed to make storage root key persistent: %v", err) | |
| return fmt.Errorf("cannot make storage for TPM root key persistent: %v", err) |
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| return fmt.Errorf("failed to configure DA parameters: %v", err) | |
| return fmt.Errorf("cannot configure DA parameters: %v", err) |
I would also expand the DA acronym to whatever it stands for.
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| return fmt.Errorf("failed to disable owner clear: %v", err) | |
| return fmt.Errorf("cannot disable TPM owner clear: %v", err) |
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| return fmt.Errorf("failed to set the lockout hierarchy authorization value: %v", err) | |
| return fmt.Errorf("cannot set the TPM lockout hierarchy authorisation value: %v", err) |
Outdated
There was a problem hiding this comment.
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.
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| return fmt.Errorf("failed to open request handle: %v", err) | |
| return fmt.Errorf("cannot open TPM request handle %q: %v", ppiPath, err) |
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| return fmt.Errorf("failed to submit request: %v", err) | |
| return fmt.Errorf("cannot submit TPM request: %v", err) |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -21,6 +21,7 @@ | |||||
| package recovery | ||||||
|
|
||||||
| import ( | ||||||
| "crypto/rand" | ||||||
| "fmt" | ||||||
| "io/ioutil" | ||||||
| "os" | ||||||
|
|
@@ -32,6 +33,7 @@ import ( | |||||
| "github.com/snapcore/snapd/bootloader/grubenv" | ||||||
| "github.com/snapcore/snapd/logger" | ||||||
| "github.com/snapcore/snapd/osutil" | ||||||
| "github.com/snapcore/snapd/recovery/fdeutils" | ||||||
| ) | ||||||
|
|
||||||
| const ( | ||||||
|
|
@@ -142,8 +144,6 @@ func Install(version string) error { | |||||
| mntSysRecover := "/mnt/sys-recover" | ||||||
| mntSystemBoot := "/mnt/system-boot" | ||||||
|
|
||||||
| keyfile := path.Join(mntSystemBoot, "keyfile") | ||||||
|
|
||||||
| if err := mountFilesystem("ubuntu-boot", mntSystemBoot); err != nil { | ||||||
| return err | ||||||
| } | ||||||
|
|
@@ -152,8 +152,16 @@ func Install(version string) error { | |||||
|
|
||||||
| cryptdev := "ubuntu-data" | ||||||
|
|
||||||
| logger.Noticef("Create LUKS key") | ||||||
| keySize := 4 * sizeKB | ||||||
| keyBuffer := make([]byte, keySize) | ||||||
| n, err := rand.Read(keyBuffer) | ||||||
| if n != keySize || err != nil { | ||||||
| return fmt.Errorf("cannot create LUKS key: %s", err) | ||||||
| } | ||||||
|
|
||||||
| logger.Noticef("Install recovery %s", version) | ||||||
| if err := createWritable(keyfile, 4*sizeKB, cryptdev); err != nil { | ||||||
| if err := createWritable(keyBuffer, cryptdev); err != nil { | ||||||
| logger.Noticef("cannot create writable: %s", err) | ||||||
| return err | ||||||
| } | ||||||
|
|
@@ -175,6 +183,31 @@ func Install(version string) error { | |||||
| return err | ||||||
| } | ||||||
|
|
||||||
| logger.Noticef("Create lockout authorization") | ||||||
| lockoutAuth := make([]byte, 16) | ||||||
| n, err = rand.Read(lockoutAuth) | ||||||
| if n != 16 || err != nil { | ||||||
| return fmt.Errorf("cannot create lockout authorization: %s", err) | ||||||
| } | ||||||
|
|
||||||
| logger.Noticef("Provisioning the TPM") | ||||||
| if err := fdeutils.ProvisionTPM(lockoutAuth); err != nil { | ||||||
| logger.Noticef("error provisioning the TPM: %s", err) | ||||||
| return fmt.Errorf("cannot provision TPM: %s", err) | ||||||
| } | ||||||
|
|
||||||
| if err := storeKeyfile(mntSystemBoot, keyBuffer); err != nil { | ||||||
| return fmt.Errorf("cannot store keyfile: %s", err) | ||||||
| } | ||||||
|
|
||||||
| if err := storeLockoutAuth(mntWritable, lockoutAuth); err != nil { | ||||||
| return fmt.Errorf("cannot store lockout authorization: %s", err) | ||||||
| } | ||||||
|
|
||||||
| if err := exec.Command("sync").Run(); err != nil { | ||||||
| return fmt.Errorf("cannot sync: %s", err) | ||||||
| } | ||||||
|
|
||||||
| if err := umount(mntWritable); err != nil { | ||||||
| return err | ||||||
| } | ||||||
|
|
@@ -196,15 +229,15 @@ func Install(version string) error { | |||||
| return nil | ||||||
| } | ||||||
|
|
||||||
| 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") | ||||||
|
||||||
| 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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
Outdated
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -24,6 +24,13 @@ | |
| "revision": "97646858c46433e4afb3432ad28c12e968efa298", | ||
| "revisionTime": "2017-08-22T15:24:03Z" | ||
| }, | ||
| { | ||
| "checksumSHA1": "M1jObMAw/YV+Rc5PccfmJuuxLa0=", | ||
| "origin": "github.com/chrisccoulson/go-tpm", | ||
mvo5 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| "path": "github.com/google/go-tpm", | ||
| "revision": "c6c7cb7465ae50e13263f2f8ff33f57d1f9859bc", | ||
| "revisionTime": "2019-07-08T13:36:22Z" | ||
|
||
| }, | ||
| { | ||
| "checksumSHA1": "iIUYZyoanCQQTUaWsu8b+iOSPt4=", | ||
| "path": "github.com/gorilla/context", | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.