TrenchBoot Anti Evil Maid - Phase 3

Introduction

If you haven’t read the previous TrenchBoot AEM blog posts ([1], [2]) or our project plan yet, it may be a good reading to catch up on what the TrenchBoot AEM project is about.

What’s new in TrenchBoot AEM?

This phase doesn’t really add any new features visible from user’s point of view. Instead, it focused mostly on bringing the code up to current Secure Launch implementation, which was still evolving when we started the AEM project. With Secure Launch code brought up to speed, we should be able to put more effort towards upstreaming soon.

Taught by our hiccups with earlier phases, we also changed our approach to testing. Now we don’t check only if the PCRs were extended, but also whether their values are correct. Qubes OS packages, created by CI, are now used wherever possible, and manually built Xen and/or GRUB are used only for development and debugging outside of Qubes OS.

Secure Launch specification

Secure Launch specification was created as an attempt to provide a unified experience in passing configuration and other meta-data to a TrenchBoot Secure Launch entry point across all supported architectures. Latest version of the specification can be found on TrenchBoot site.

The document starts with an overview of architecture, which describes what components take part in dynamic launch, together with interactions between them. It is followed by description of Secure Launch Resource Table (SLRT), which takes majority of specification.

One very important part of SLRT called DRTM Measurements Policy describes what components have to be measured by DLME (Dynamic Launch Measured Environment, Xen in our case). The size of this entry may vary to provide flexibility for different number of components. This allowed us to properly measure more than just two of modules passed to Xen (dom0 kernel and initramfs), so previous limitation that excluded microcode and XSM has been lifted.

Addition of Multiboot2 protocol to the Secure Launch entailed new entry type for modules. This was not added to the specification yet, we’re still gathering all small fixes that can be done before next revision in this issue.

Installation

From user’s point of view the installation process is virtually the same as before. Follow instructions from the previous blog post and you’re good to go. Just remember to use binaries for v0.3, which can be downloaded from here. The same components have to be installed as before, but keep in mind that their revisions are different, so you can’t just copy and paste the instructions as they are in previous post. This shouldn’t be a problem, you don’t mindlessly run commands suggested by some random guy on the Internet in dom0 anyway, right? :)

If you’re updating from previous AEM version, keep in mind that unsealing will fail on the first boot. This is expected, and it is described in AEM README.

Testing

One additional change visible for the user is the ability to dump TPM event log. A script doing just that is part of anti-evil-maid package. It can be run as root in dom0 by calling sudo anti-evil-maid-dump-evt-log. Example output obtained on HP EliteDesk 800 G2 with Intel Core i5-6500T:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
Found 2 algorithms:
    ID 0x0004 size = 0x14
    ID 0x000b size = 0x20
vendorInfoSize = 0
Entry 1:
    PCR:        17
    Event Type: 0x402
    Digests:
      SHA1: 1b065ab77c6b571ef8c96b061f4af99579c0d94c
      SHA256: 3ff357bf27dca3dab8cfdf42cc848b1f5239b2114f1b5ce1f9975019b61a859a
    Event: 663c20d7579a2d43be46e2972cc58ad4a9d76c83efaee1ddc28bf9a167edb01000000000
Entry 2:
    PCR:        255
    Event Type: 0x401
    Digests:
      SHA1: 0000000000000000000000000000000000000000
      SHA256: 0000000000000000000000000000000000000000000000000000000000000000
    Event: 01000000
Entry 3:
    PCR:        17
    Event Type: 0x40a
    Digests:
      SHA1: 98492d9d1e7b49eb32135dca3887bbfe35a5b3dc
      SHA256: 7e9e5ef138613f5999d149f0357edf4ff6f7573703a126bedd76c7398676c30c
    Event: 000000002905192006b000000002000000000000000000000000000000000000
Entry 4:
    PCR:        17
    Event Type: 0x40b
    Digests:
      SHA1: 9069ca78e7450a285173431b3e52c5c25299e473
      SHA256: df3f619804a92fdb4057192dc43dd748ea778adc52bc498ce80524c014b81119
    Event: 00000000
Entry 5:
    PCR:        17
    Event Type: 0x40c
    Digests:
      SHA1: 0aaf76f425c6e0f43a36197de768e67d9e035abb
      SHA256: 26b25d457597a7b0463f9620f666dd10aa2c4373a505967c7c8d70922a2d6ece
    Event: 02000000
Entry 6:
    PCR:        17
    Event Type: 0x412
    Digests:
      SHA1: 5ba93c9db0cff93f52b521d7420e43f6eda2784f
      SHA256: 6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d
    Event:
Entry 7:
    PCR:        17
    Event Type: 0x40e
    Digests:
      SHA1: 5ba93c9db0cff93f52b521d7420e43f6eda2784f
      SHA256: 6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d
    Event:
Entry 8:
    PCR:        17
    Event Type: 0x40f
    Digests:
      SHA1: 246445653fc4dcf9efd5c7e88036f34bebda30f3
      SHA256: 5c09817a86d6dce28033e2fa3b6c2d9b292548f8ad06121032a187647eaf1150
    Event: 26020000
Entry 9:
    PCR:        17
    Event Type: 0x404
    Digests:
      SHA1: 295d3653dcdd341b52cb8c3081e966c243a2fcc9
      SHA256: 655d06387527d96f66d07ceff3ae855e27229f88873ef8b2e12d0a6825420540
    Event:
Entry 10:
    PCR:        17
    Event Type: 0x414
    Digests:
      SHA1: 5dfea6ad59169b181f5cbc08e84455fa0e289161
      SHA256: 8e22a74383846c88d1b09099ae44bfb1b2d983be6daef20883fd9ffb9f4babd6
    Event: 0101800003000b620444080020ef9a26fc22d1ae8cecff59e9481ac1ec533dbe228bec6d17930f4cb2cc5b972400680101800001000b62042c040020b75ce1946f78df8baa426918db09318017e6b38d048c954e05c2c4f34bd44060004600
Entry 11:
    PCR:        18
    Event Type: 0x410
    Digests:
      SHA1: e75b9b930232d8061f2a637e6a59501a418bd3da
      SHA256: 3b5f9781c4347f5d3af1daf7019654dc05d1af857a598c18f3bc77e7b042b37f
    Event:
Entry 12:
    PCR:        18
    Event Type: 0x40b
    Digests:
      SHA1: 9069ca78e7450a285173431b3e52c5c25299e473
      SHA256: df3f619804a92fdb4057192dc43dd748ea778adc52bc498ce80524c014b81119
    Event: 00000000
Entry 13:
    PCR:        18
    Event Type: 0x40f
    Digests:
      SHA1: 246445653fc4dcf9efd5c7e88036f34bebda30f3
      SHA256: 5c09817a86d6dce28033e2fa3b6c2d9b292548f8ad06121032a187647eaf1150
    Event: 26020000
Entry 14:
    PCR:        18
    Event Type: 0x40c
    Digests:
      SHA1: 0aaf76f425c6e0f43a36197de768e67d9e035abb
      SHA256: 26b25d457597a7b0463f9620f666dd10aa2c4373a505967c7c8d70922a2d6ece
    Event: 02000000
Entry 15:
    PCR:        18
    Event Type: 0x413
    Digests:
      SHA1: 5ba93c9db0cff93f52b521d7420e43f6eda2784f
      SHA256: 6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d
    Event:
Entry 16:
    PCR:        18
    Event Type: 0x414
    Digests:
      SHA1: 5dfea6ad59169b181f5cbc08e84455fa0e289161
      SHA256: 8e22a74383846c88d1b09099ae44bfb1b2d983be6daef20883fd9ffb9f4babd6
    Event: 0101800003000b620444080020ef9a26fc22d1ae8cecff59e9481ac1ec533dbe228bec6d17930f4cb2cc5b972400680101800001000b62042c040020b75ce1946f78df8baa426918db09318017e6b38d048c954e05c2c4f34bd44060004600
Entry 17:
    PCR:        18
    Event Type: 0x502
    Digests:
      SHA1: bac7df776a03c276f35e603ce0cfc4fee9068eb7
      SHA256: 9d1e2290b628e3d676b9d6141373f84c63d48264bea634518d3fa25134108c18
    Event:
Entry 18:
    PCR:        18
    Event Type: 0x502
    Digests:
      SHA1: 3b5432648ef18ec462425018faf869b0f8f000f5
      SHA256: 32e56f2deb41d7a5eb5b0ae176d28c79704e781aade583faf19df1ad090e1e3d
    Event:
Entry 19:
    PCR:        18
    Event Type: 0x502
    Digests:
      SHA1: 2a967d058b9b05947a45eecc7620126af10b95da
      SHA256: c65dbff6e597353bd110c84a032baec0e986c997f110c9a21a11866ea9eda393
    Event: Measured TXT OS-MLE data
Entry 20:
    PCR:        17
    Event Type: 0x502
    Digests:
      SHA1: 36bb39b7fe9f45cf3dc1c8eff1f471601d18c2b4
      SHA256: 93d3fda97f1bc58402526248e59edbecf32d058f9a372dc43c9e55a777d60812
    Event: Measured MB2 module
Entry 21:
    PCR:        17
    Event Type: 0x502
    Digests:
      SHA1: 501fe83e26ed23d319dd61dd8dfe347e32dc1ae5
      SHA256: f4d74eee90a45cbc5d75a98dd5d688b7fd3635bb44e7afd46990df67561d6da7
    Event: Measured MB2 module

To verify PCR values are correct digests from the entries can be extended using debug PCR 16 (make sure it is reset before starting!) and compared with actual values of PCR 17 and 18.

There is a bug in older ACMs (we’ve noticed it on Skylake/Kaby Lake, it may be present also on other processors from that period) that causes the first entry in the log to contain result instead of input digest. This can be worked around by taking SHA1 of Event of that entry, e.g. by running echo "<hex-string of event>" | xxd -p -r | sha1sum, and using that to extend the PCR instead of whatever was logged. To the best of my knowledge, Intel never publicly acknowledged this bug, but if anyone has a trusted source that can be quoted, please add a comment about that at the bottom of the page.

Known issues

We’ve noticed few issues that we share here for full transparency:

  • Bad measurement logged by ACM. This isn’t exactly something we can fix, as ACM is closed-source binary signed by Intel, and Intel won’t fix such old and no longer officially supported CPU family. What we may try to do is to catch this problem in parser, inform the user about it and print proper value.
  • Xen on HP mentioned above doesn’t bring up all cores after TXT launch. This doesn’t happen on any other platform we tested. “Clean” Xen without patches applied for Qubes OS (but with AEM patches we developed) doesn’t exhibit this problem, neither does it happen if Qubes OS is started without AEM - it seems that there is some interaction between those, we’re still debugging it.
  • There is no textual description of events logged in early environment, even though that data is available as part of DRTM Measurements Policy. Passing it to function that does the measurement and logging would require calculating string length and strnlen() is not available for linking in early code.
  • Xen doesn’t measure and log SLAUNCH_START and SLAUNCH_END entries. These are used to mark beginning and end of measurements to not allow any software running either before or after to create entries impersonating expected components.
  • S3 still wasn’t tested, and probably doesn’t work, or worse: works insecurely.

Next steps

As said in the introduction, code that uses SLRT is now close enough to the final form that we can safely focus on upstreaming it. In fact, SMP bringup already has been sent to xen-devel mailing list. It is common code used by every Xen boot (on x86) so it went separately, mostly as a way to introduce ourselves before dropping relatively big new feature that a handful of people would ever use. Next sets of patches will probably target QubesOS organization on GitHub before true upstream sources. That way we will be able to get review from final users of AEM before bothering wider audience.

Next phase will bring support for AEM to AMD processors. This should make it easier, cheaper, and generally more available - for TXT you need vPro processor, but for AMD you just need any processor, starting with Athlon 64. Anything younger than 15 years should do, as long as the platform has a discrete TPM.

How you can help

By testing, of course! Install AEM, see if it performs as it should and report any encountered problem in trenchboot-issues repository.

Spreading the word is another way of helping. The more people know about AEM the better. We may not be able to test it on every possible configuration, but perhaps others have platforms that we don’t.

You can also stay updated on our project’s progress by visiting our GitHub milestones, and join our discussions in the public Matrix channel, where everyone can participate and share their thoughts.


Krystian Hebel
Firmware Engineer interested mostly in things deliberately omitted from documentation. Thinks C is high-level language, can write something in Verilog but doesn't know how to read it yet.