-
Notifications
You must be signed in to change notification settings - Fork 17
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
preinstall: Add initial checks for TCG log consistency with PCR values #319
preinstall: Add initial checks for TCG log consistency with PCR values #319
Conversation
3b23972
to
28e0454
Compare
0c803fc
to
bbe4284
Compare
2147496
to
64dc595
Compare
64dc595
to
e080181
Compare
This adds a function that verifies that the TCG log is well formed and is consistent with the TPM's PCR values for at least one supported PCR bank. On success, it returns the best PCR bank to use and the startup locality, and any errors that occurred for non-mandatory PCRs. A PCR might not be mandatory because we don't have a way to generate profiles for it, or because the input flags to RunChecks marked it as optional. The startup locality is used later on with the discrete TPM indication returned from the earlier TPM check to customize the PCR profile. It performs some other tests, notably that: - the TCG log contains a sequence of expected phases. - the TCG defined PCRs contain a EV_SEPARATOR event between the pre-OS and OS-present environment (although the one in PCR7 separates secure boot policy from secure boot authentication). - none of the EV_SEPARATORs in the TCG defined PCRs indicated that an error occurred. - there are no pre-OS measurements to non-TCG defined PCRs (8-). Future PRs will add more specific checks for each supported PCR. This pulls in a newer go-tpm2 for TPM2_PCR_Allocate support in the library and test harness. This is a function that's normally ever called from firmware, but we need to be able to do what the firmware does to enable/disable PCR banks here.
e080181
to
9d73305
Compare
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.
did an initial pass
data := tcglog.StringEventData("1.0") | ||
builder.hashLogExtendEvent(c, data, &logEvent{ | ||
if opts.StartupLocality == 4 { | ||
ev := &tcglog.Event{ |
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.
a brief comment describing what is happing here could be useful
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.
I've added a comment to this.
{pcr: 0, eventType: mockPcrBranchExtendEvent, digest: testutil.DecodeHexString(c, "cd1137dfa2bfba51973100d73d78d9f496e089fd246fe980fadc668b4efc9443")}, | ||
{pcr: 0, eventType: mockPcrBranchExtendEvent, digest: testutil.DecodeHexString(c, "5ca5e6acb83d626a42b53ddc5a2fe04d6a4b2f045bb07f6d9baf0e82900d7bbe")}, |
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.
are these because of the changes in efitest/log.go ?
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.
They are.
efi/preinstall/errors.go
Outdated
return w.String() | ||
} | ||
|
||
// UNwrapBankError returns the error associated with the specified PCR bank if one |
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.
typo
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.
efi/preinstall/check_tcglog.go
Outdated
results.Lookup(ev.PCRIndex).setErr(errors.New("unexpected StartupLocality event (should be in PCR0)")) | ||
continue | ||
} | ||
if !bytes.Equal(results.Lookup(0).logValue, results.Lookup(0).initialValue) { |
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.
shouldn't this check be a predicate on the struct?
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.
Yes, they could be
efi/preinstall/check_tcglog.go
Outdated
return &tcglogPhaseTracker{ | ||
phase: tcglogPhasePreOSBeforeMeasureSecureBootConfig, | ||
numSeparatorsSeen: 0, | ||
pcrSeparatorsSeen: make(map[tpm2.Handle]struct{}), |
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.
nitpick: we tend to just use bool and not empty struct for this kind of set structures
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.
I can change that.
// An EV_SEPARATOR event in PCRs 0-6 after measuring the secure boot configuration begins the | ||
// transition to OS-present, skipping the part of the pre-OS phase after the secure boot config | ||
// has been measured. | ||
t.phase = tcglogPhaseTransitioningToOSPresent |
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 case is not tested
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.
Aha, I'll see if there's something I can do to test that. At the moment I'm just doing ad-hoc modifications to logs to break things.
Note that the next PR currently has quite a low coverage because it's got a switch statement with a lot of branches to cover all possible event types. We have tests for the most common types that we're likelly to see, but testing all of the others is going to require significant work in internal/efitest
to customize the log and generate events with different types. I'm not sure whether that will be a blocker for the first iteration, especially as Oliver is keen to get this landed.
} | ||
} | ||
if !phaseTracker.reachedOSPresent() { | ||
return nil, errors.New("reached the end of the log without seeing EV_SEPARATOR events in all TCG defined PCRs") |
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 error case is not tested
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 one should be easy to figure out how to test.
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.
I've added a test for this one now.
This reduces some code that's duplicated in a few places.
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.
thank you, should Mate or somebody else familiar with boot give a look a this?
Sure, I can ask @kukrimate if he would like to take a look at this too before we land it. |
This adds a function that verifies that the TCG log is well formed and
is consistent with the TPM's PCR values for at least one supported PCR
bank. On success, it returns the best PCR bank to use and the startup
locality, and any errors that occurred for non-mandatory PCRs. A PCR
might not be mandatory because we don't have a way to generate profiles
for it, or because the input flags to
RunChecks
marked it as optional.The startup locality is used later on with the discrete TPM indication
returned from the earlier TPM check to customize the PCR profile.
It performs some other tests, notably that:
and OS-present environment (although the one in PCR7 separates secure
boot policy from secure boot authentication).
error occurred.
Future PRs will add more specific checks for each supported PCR.
This pulls in a newer go-tpm2 for
TPM2_PCR_Allocate
support in thelibrary and test harness. This is a function that's normally ever
called from firmware, but we need to be able to do what the firmware
does to enable/disable PCR banks here for unit testing to emulate
different firmware configurations.