TrEE vs TCG

I’ve been learning a bit about UEFI and the new TPM2 specifications these past few weeks. My work in this space isn’t ready for public consumption but I’ve run into some interesting data worth mentioning here. I got really stuck on this on account of my UEFI stills being very weak. Thankfully others ran into the same issue and shared their knowledge. I’m putting this up in the hopes of keeping others from falling down the same hole that took up so much of my time.

Dueling Specifications

When I started poking at the 2.0 TPM on my Minnowboard Max, knowing the interplay between the Microsoft TrEE and the TCG TPM 2.0 EFI Protocol specifications would have saved me a pile of time. AFAIK Microsoft is a very big contributor to the TPM 2.0 specs and Windows 8 and 10 both build on it for security infrastructure. The new TPM specs from the TCG are still in draft form and out for pubic review which is good, but Microsoft is shipping real live systems that use with version 2.0 TPMs.

I don’t participate in any of the TCG stuff other than writing software that uses the TPM so I’ve got no inside knowledge here, but I speculate that it’s hard to ship systems when a core component doesn’t have a published interface specification. So what to do? Microsoft published their own version of the TPM UEFI version 2 Protocol specification under the Trusted Execution Environment EFI Protocol name. You can argue that this isn’t the same as the TCG EFI Protocol Specification for TPM Family 2.0 Revision 1.0 but by UEFI law these two protocols have the same GUID and so they’re the same protocol. Period.

Same GUID, Subtle Differences

So Microsoft published a version of the specification early to support their customers and developer community. I don’t see that they had any other choice. But how does this cause problems you ask? Grab your Minnowboard Max, install the 32bit firmware so you get the Intel PTT (firmware TPM2), code up an EFI application that calls the GetCapability function from the protocol and you’ll see. The short version is that there is a subtle difference in the two specs that causes incompatibility. The TCG spec clearly states that all structures in the spec are packed. The Microsoft spec on the other hand says nothing about struct packing outside of the code samples. Their samples however use macros #pragma pack(1) to show which structures should be packed and the TREE_BOOT_SERVICE_CAPABILITY (synonymous with the TCG EFI_TCG2_BOOT_SERVICE_CAPABILITY structure) is not defined with this macro in effect.

The end result is that since Microsoft is (AFAIK) the only platform currently supporting TPM2, all TPM2 hardware / firmware out there implements their TrEE spec. The UEFI protocol implemented on these platforms will return to you an unpacked struct when you call the GetCapability function and if you’re like me and you’re working from the TCG draft spec you’ll be banging your head against the wall for a bit.

Lessons Learned

Pretty interesting first exposure to UEFI and TPM2. Painful in that my UEFI debugging skills are pretty weak. Interesting caus I’ve learned a ton. Checking structure packing is now at the top of my debugging check list. It’s also very interesting to see dueling specs like this. The reality of having to ship hardware / firmware / software before a specification is finalized has got to be a tricky business so it’s hard to fault Microsoft for this.

The relevant upstreams know about this issue thanks to Matthew Garrett and I’m sure they’ll resolve it before the TCG spec is finalized. Most likely the TCG draft spec will be updated and the capability structure will officially not be packed. Don’t bank on this though. YMMV and every other possible disclaimer.

An additional foot note is that the current TCG spec prescribes conflicting version numbers for the StructureVersion and ProtocolVersion fields in the capability structure too. I’ve reported this as part of the public review process as well.

meta-measured updates

I’ve been grinding down updates to meta-measured slowly but surely over these past few days. This was started a while back but slowed to a stop when I got distracted by work on meta-selinux. Last week my work to upgrade the SELinux toolstack was merged upstream so I’m re-focusing on getting meta-measured back in shape. This is a quick run down on the changes.

General Maintenance and Release Tracking

I haven’t been chasing upstream much so most of this work has just been maintenance. The kernel in OE has moved forward with 4.1 the new stable in master. The read-only root file system class was broken when I tried a fresh master build the other day. When jumping in to start a refresh, finding core features broken can be a bit discouraging. Instead of taking on this fix immediately I figured it would be best to create a branch to track the latest release (fido) and get that working first. I’ve always avoided tracking OE releases because I don’t want to give the impression that meta-measured is in any way “stable”, as if having my master branch broken on a regular basis wasn’t a good enough indicator.

Seriously though, I kinda dropped the “chasing master” ball. Having a branch that follows the latest release is a good way to make getting everything up to date and it’s a good insurance policy against future breakage in master. So win / win on that. Fido still has a functional readonly-rootfs class so, for the 2 other people out there who have kicked the tires on meta-measured, fall back to a release branch. My goal is to keep at least one release branch in working order.

There are two changes between fido and the current master that have an impact on meta-measured. The first is the upgrade to GCC5. For the trousers and tpm-tools packages this requires a patch that I’ve gratefully borrowed from the hardworking people over at the Debian project. The other is meta-intel nuking the meta-nuc layer. This is a pretty minor change and I’m now using the measured-intel-corei7-64 that extends the intel-corei7-64 machine from meta-intel on the master branch. Fido still has the NUC machine so I’ll stick to that for Fido.

systemd

The first external submission to meta-measured came in a few months back. This was to add systemd support to the trousers package. I had done something similar to this as part of some work to get meta-measured working with the Edison but it was in the BSP layer. It really shouldn’t have been in the BSP layer to begin and my implementation was a hack regardless. The patch I received that adds this feature directly to meta-measured was well done so I’ve added it directly and removed my hack from the BSP.

The only bit I didn’t like from the patch was a utility script that loaded every TPM module under /lib/modules/$(uname -r). This seems a bit heavy handed given that modern Linux kernels autoload these modules when the device is detected. Pretty minor change though and this is now in meta-measured proper.

IMA and TPM2

I started playing around with configuring IMA a while back as a way to exercise the TPM2 that’s baked into the Minnowboard Max as part of PTT. I don’t have any specific plans to do much with IMA just yet but with the xattrs patches I pushed into meta-selinux I’m hoping to be able to support IMA appraisal. It would be a great use case and demonstration to show the utility of my xattr work with an OE image booting with IMA appraisal enforced from firstboot.

UEFI Breakage

I’ve been saving the bad news for last unfortunately. Somewhere in the changes that have been going on with OE, my bringing meta-measured up to date and flashing the firmware on my IVB NUC, measured-image-bootimg broke. I’m pretty sure this is a problem with the latest firmware for the NUC but that’s a guess. Grub2 comes up OK but tboot doesn’t seem to take over.

In prevous debugging I learned that tboot won’t log to VGA since UEFI doesn’t setup a text console for use by whatever executes after ExitBootServices() is called. It’s frame buffer only in UEFI world I guess. But tboot would still log to a serial device through direct I/O. Not this time though. Once Grub2 kicks off tboot my NUC is unresponsive and I get no additional output. Booting straight to the kernel from grub works fine but going the tboot route through multiboot2 isn’t working.

I’m pretty much out of debugging ideas here. My test system is getting a bit old and it’s the only UEFI system I have for use here so I’m writing this off as a loss for the time being. If anyone out there is testing this on a UEFI system I’d love to hear about whatever results you have to report.

Next steps

I’ve added the contributed systemd support to trousers but I haven’t enabled or tested systemd support for my reference images. This is next on my list of things to do. I’ve got trousers working on a systemd driven image previously in some work to wire a TPM up to an Edison system (more on this in the future hopefully) but I was working on on the reference Edison images. Stay tuned and hopefully I’ll have proper systemd support in the near future.

xattrs in OE rootfs part 2

This is an update on some work from a previous post. My xattr patches sat on the yocto mailing list waiting for meta-selinux maintainers to review them for about a month. I got a bit testy and even commented to another contributor off list about the possible need to fork given the lack of response from maintainers. Turns out that this contributor was using his gmail account but actually works for the same company as the maintainer. So about 24 hours later the maintainers magically reappeared and merged my patches!

I really have no interest in forking and maintaining meta-selinux so this was a win. Hopefully I didn’t look like too much of a jerk in the process … ¯_(ツ)_/¯ After a quick stint in a feature branch my xattr code was merged into meta-selinux master. This is only a step in the process though. These patches really belong in the openembedded-core repository. They can likely be moved with minimal effort on the technical side. Getting traction for these sorts of fringe features upstream however takes a bunch of time though, as demonstrated by the 2 months it took to get this into meta-selinux.

As a strategy I should probably prove out an additional use case beyond SELinux file labels. I did some work on meta-measured a while back to add basic IMA support. I really want to expand this to support IMA appraisal. I’m not a huge fan of local enforcement policies but this use case is a great example of build-time xattr usage that would demonstrate the utility of my xattr patches. This is all food for thought though at this point.

Building and Booting Grub2 for a UEFI System

I’ve been playing around with Grub2 a bit while trying to learn something about UEFI. Long story short: I’m really interested in the current measurement gap between the UEFI environment and the Linux OS. Before I go too far into those details I just wanted to get a quick note up on building Grub2 for a UEFI target, specifcally the x86_64 (aka amd64) target.

WARNING: This post won’t help you get Linux or any other OS booted from Grub. I’m only covering the steps necessary to build Grub for the efi target and setting up a UEFI boot disk to run it. That’s all.

Build

Doing the actual build is the easy part. First things first: get the source from the GNU project website. Then RTFM in the INSTALL file. For my setup, specifying --target and --with-platform. The build goes something like this:

./autogen.sh
./configure --target=x86_64 --with-platform=efi
make

UEFI bootable USB

UEFI is a huge departure from the legacy BIOS world. To keep this post short we won’t spend any time discussing BIOS but if you’ve ever wrestled with fixing a broken grub-pc install you’ll know what I mean. Installing or fixing a UEFI Grub system by comparison is pretty simple:

  1. Format a disk (USB in my case) with a GPT using your favorite partitioning tool.
  2. Create a partition with the appropriate type for UEFI. Unfortunately the name for this type is different depending on which partitioning tool you’re using. I use fdisk and the type is ‘EFI System’. It doesn’t need to be large, just enough to hold the grub executable. I made mine 100M which is extremely large. Make note of the UUID of the partition.
  3. Format the partition as FAT16 or FAT32.

Create the UEFI Executable

This builds everything but we don’t yet have a UEFI executable. To create one you’ll need to run the grub-mkimage utility. This is the root of the build directory and it’s responsible for stitching the grub kernel, core modules and a builtin config to bootstrap grub. Generally you’d only build the minimally necessary grub modules into the UEFI executable but since this is for my debug setup I’m going to build every module in. This makes the executable very large but it’s easier.

Before we can do this we need to grok the idea of the builtin config. Grub needs a hint when it comes to setting up the system. For my purposes all I care about is getting the FAT partition mounted so my config just tells Grub how to find the root partition and what to set as the prefix.

(
  cat < grub-buildin.cfg

The --fs-uuid is pretty self explanitory. The UUID in the above code fragment isn’t the actual UUID of my UEFI system partition. If you’re following along at home you can get the UUID for the FS you created above using the blkid utility. The prefix tells Grub where to look for the grub.cfg configuration. We won’t even supply one here so the system will boot straight to the grub shell.

Since we’ve specified the prefix in the builtin config the -p option below is useless but grub-mkimage throws an error if it’s not provided. The value we pass is obviously wrong but the image produced will still function.

Finally execute the command:

./grub-mkimage -d ./grub-core -o bootx64.efi -O x86_64-efi -c ./grub-buildin.cfg -p /foobar $(find . -name '*.mod' | tr 'n' ' ' | sed -e 's/.mod//g')

Setup the Boot Disk

By default UEFI firmware will look for the bootloader on a disk at /EFI/BOOT/bootx64.efi. So all we need to do is mount our EFI system partition, create the /EFI/BOOT directory and copy the bootx64.efi executable there. In the above command we built in ever module that Grub has so we don’t need to worry about copying over any modules.

And that should do it. Point your system to this USB device, boot up the grub efi executable and you should go straight to a Grub shell. If you want to get an OS up and running on top of this you’ve still got a long way to go. But if you’re like me and just screwing around with grub (more on this later) then you’ve got a pretty good test environment. Now all you need to do is write a quick config to get Grub logging to some serial hardware and crank up the debug output!

Purism, the TPM and the FSF

Alright, I’ll come out and say it: I’m optimistic about the Purism / Librem project. The impending release of their first product is really exciting. Their goals are extremely ambitious (the hallmark of a worthwhile project) and despite having come up short of their stated goals and receiving some harsh though justified critique on the web, they’ve still produced a laptop that’s shipping soon. And so my optimism is holding out.

This is my first post on this topic and is mostly introductory: basically why I care about the project and the subject in general. My goal is to develop a series of posts discussing freedom and security (two things that I’m convinced are related) in the context of general purpose computing and the Purism Librem laptop. If you love freedom, free software and computer security, read on … if not, read on anyways.

Criticism from the Web

Not everyone is as impressed with Purism as I am, and the best articulation I’ve found is from Alexandru Gagniuc on the coreboot blog. The TL;DR is that people have been working in the free hardware space for a long time. The impression is that Purism showed up and claimed that they could do in 6 months what others have been working towards for years. Many have taken this as a sign that something is amiss. Those working in OSS see this sort of stuff all the time: someone shows up on your mailinglist with big plans, lots of enthusiasm … and then they figure out how much work it will take and you never hear from them again. I’m hopeful that, despite falling short of their initial goals, the folks at Purism stick around and continue to chip away at their stated goals.

Something that I find particularly troubling is the increasing rhetoric on the Purism website around “fighting for your freedom” all while hedging on past promises. The new video on their homepage with the young cartoon woman flying their flag and weeping cartoon tears for her lost freedoms has set my instinctive negative reaction to over-the-top marketing into high gear. Add to this some genuine and public concerns over the claims made by Purism and I’d say that they’ve got a bit of digging to do if they want to get out of this hole.

Lesson to learn: Grand or unrealistic claims about security, privacy-preserving and software freedom won’t go unnoticed or unchallenged when your target audience knows what’s up. Purism is catering to a niche market. Their target audience is extremely savvy about these things and they’re not going to be shy about “calling bullshit”. Skeptics are going to be skeptical, they’re going to demand proof. This is a good thing.

Continued Optimism

Despite all of this, I’m still optimistic about the project. Even better, the folks at Purism seem to be paying attention to their critics. They’ve published a road map detailing the steps necessary to reach their stated goal of FSF RYF (respects your freedom) certification. No doubt it’s going to be an uphill battle and the folks over at coreboot may be right: the entirety of the firmware may never be OSS. But having an OEM who actually wants to fight for the user will never be a bad thing so long as they don’t alienate their target audience in the process. In a time when OEMs are getting busted for integrating ad/spy-ware into their firmware we need a change.

The Future: Freedom and Security

This is probably going to get dangerously close to an attempt to predict the future, but I’m very hopeful for Purism and their products. I haven’t been following too closely but when I looked the other day, sure enough the specs for the Librem 15 list a TPM and it’s a version 2. Sweet. More on this in a future post.

Additionally, the FSF has endorsed CrowdSupply (the crowd funding platform used by Purism). I’m trying not to read too far into this but I can’t help but think that this represents an organized push from free software movement into hardware while adopting the pro-security-and-privacy rhetoric that’s become so relevant in the wake of the Snowden revelations.

I generally think of myself as a pragmatist when it comes to running purely open source software. This may just be a result of the need to load proprietary / binary firmware to get the wireless card on my laptop to function properly. It also could be related to my love of security technologies and the fact that the FSF has taken such a hard-line in their labeling of the TPM as malicious, a position I’ve always viewed as misinformed. I’m hopeful that the Purism project can help mend the rift between the free software movement and the security technologies that are essential to preserving our freedoms in an increasingly hostile computing environment.

This post was a sort of introduction, just some background about why I care about the Purism project. In my next post I’m hoping to get into why I think freedom and security have become so closely related. Stay tuned.

Nagasawa

My posts have been very sparse recently. Even less frequent have been posts on non-technical topics. To stay true to the title of my blog I’ve gotta step up my posts on “two-wheeled vehicles”. That or change the name. Changing the name would require digging through WordPress menus and since that’s my least favorite thing to do I ran out and got another bicycle so I could blog about it … and ride it.

Nagasawa makes a pretty serious track frame. More serious than me for sure but when I saw this thing on CraigsList I couldn’t resist. It was meant to be. Nearly everything on it is NJS and it’s in very good shape. A few chips in the paint here and there but nothing beyond standard wear. Even better, it’s the right size. You don’t find very many Japanese track bikes that fit someone over 6 feet tall.

The guy I bought it from had it set up for track riding. Since I’ll be riding it on the street I’m in the process of taming it a bit. First things first: get rid of the NJS track seat (aka the “ass-hatchet”). Then I’ll probably have to drop the gear ratio a bit. The wheels are super nice but they’re not beefy enough for every day street riding. I’ll have to start saving before I can get a new set.

Till my next post, enjoy the obligatory bike porn:
Nagasawa-headtubeNagasawa_front-rightNagasawa_right-rear

OXT and Paying Down Technical Debt

The few people out there who have slogged through the process of building OXT know how painful it is / can be. One of the most significant contributors to the difficulty here is the amount of technical debt that has built up in the build system over the years. We always “got it to work” when doing build stuff, but with the rate of change in the OE project / community we never kept pace with “doing it right”.

The reasons for this are many and every developer out there is familiar with the “ship it” pressures that tip the scales from “do it right” to “just make it work”. I won’t get into that here because it’s just the way things are now. What’s interesting and useful IMHO is coming up with a way to tip the scales back now that the pressures / incentives are different. So this post will cover some of my work to pay down some of the technical debt that I think is particularly important.

File Systems and Xattrs

One of the unique opportunities afforded us by the OE build system is the ability to produce complete file systems. When we do an install of OXT we don’t have to muck around in the file systems of any of the service VMs (including dom0) because they’re all ready to go straight from the build system. This means we can boot them read only from first boot. With a little bit of work, we could even do a measured launch from first boot complete with predictable measurements.

One of the hurdles we had to overcome was the need for xattr support in the file system creation code. Refusing to have a bunch of “first boot” code to put band aids on the shortcomings of our build system means that we had to come up with a way to create xattrs in the build and have them preserved through the creation of the service VM file systems. This is a problem that the usptream meta-selinux OE layer suffers from currently as anyone who’s built the core-image-selinux image will tell you. They have first boot code that detects the unlabeled file system, relabels it accordingly and then reboots. Only after this first reboot will the system come up with SELinux functioning properly.

Upstreaming xattrs into e2fsprogs

Having some common ground with an upstream like this seems like a good first step. Nothing like a shared problem / need to motivate work. For the OXT community getting this upstream will get us one step closer to being able to build service VMs for OXT (including our own) that don’t depend on a pile of old build metadata and an ancient version of bitbake.

The bits that need to go upstream are actually pretty small. We had to hack up a patch to Pseudo to get that to support xattrs but upstream Pseudo has already implemented this functionality and they did it right. When I saw that Pseudo had already implemented this I was relieved as it probably cut the amount of effort required in half. This left getting the actual disk image produced by the build to support xattrs.

gene3fs was the OXT tool that we used to get the build to spit out ext3 file systems. This is a departure from upstream where they have patches added to the e2fsprogs mke2fs utility. This work wasn’t mine but gene3fs looks like a fork of the unmaintained gene2fs project adding support for the ext3 file system, xattrs and VHDs. Even if this approach is technically superior to the usptream method it’s a moot point. Upstreaming is about longevity.

So ignoring the VHD stuff for now I’ve implemented a set of patches for OE that add xattr support to the build. With these patches in place we can apply SELinux labels to a root file system and boot the resulting image into enforcing mode without having to do first boot fixups. Stage one complete!

Getting patches merged

The hard part about sending stuff upstream is motivating maintainers to merge the patches. meta-selinux is pretty sparsely maintained unfortunately and 3 weeks after having sent my patches to the Yocto mailing list I haven’t had anyone test or even respond to the post. I’m not sure which is worst: being ignored or having someone tear apart the patches because they suck.

Trying to keep from being too persistent / obnoxious I’ve left these patches alone for a bit. Thankfully the e2fsprogs package is one of those critical pieces of the build system and so the maintainers seem to favor stability over frequent updates. This means the likelihood of having to rebase my patches is pretty low. If I don’t get some attention from the meta-selinux maintainers soon I’ll likely rebase them into the openembedded-core layer and send them there. I think the need for this functionality is less understood there but they’re much more active and likely to provide feedback (even if it’s “no thanks”).

Tracking work

We haven’t had a lot of upstreaming work done for OXT yet so there’s not really a process in place for tracking such efforts. As such I’ve created a place on the confluence wiki where I’ll track this stuff. The SELinux / xattr specific stuff is here: https://openxt.atlassian.net/wiki/display/~flihp/SELinux+file+system+labeling+in+build
I’ve set up a page describing the general process I’m following as well and that’s here: https://openxt.atlassian.net/wiki/display/~flihp/Upstreaming

If anyone else is working on sending functionality upstream regardless of where feel free to work off these pages. Once we’ve got a few examples to work from we may decide to formalize the process but for now I’m just trying to pay down some technical debt and make some progress both for OXT and one of the usptreams we share common goals (and hopefully code) with.

PGP links

I wish PGP was easier to use. When it comes to having to invoke gpg directly I usually spend some time with the man page and that’s enough. But when it comes to the more detailed stuff like setting algorithm preference or identities I always fall back to the collective internet knowledge. I think I’ve looked up the following links a few times now and I’m leaving them here for reference:

https://wiki.debian.org/Subkeys
https://www.debian-administration.org/users/dkg/weblog/48
http://blog.infertux.com/2013/11/03/how-to-remove-an-email-address-from-a-gpg-key/

HP Elitebook 820 G1 laptop dock script

Upgraded my laptop from an ancient HP 2760p so it’s time to write a new script to handle plug / unplug events from the docking station. Wait, what? Write a new script? Haven’t I done this before? Sure, I wrotea docking script for my Thinkpad x61s, but that was 6 years ago. No way that script still works … no wait it does!

Minor tweaks to sort out some differences between the udev events for the thinkpad / elitebook and changes to the xrandr command for my current monitor setup and it’s good to go!

The thinkpad had better integration with the kernel ‘dock’ driver so it generated different events for ‘dock’ and ‘undock’ events. For the EliteBook I had to trigger on the DRM kernel subsystem getting a ‘change’ event on ‘card0’. Not sure what that means but it’s consistent for plug / unplug. To determine whether the ‘change’ is docked or undocked I’m parsing xrandr output to see which monitor is present where. It’s not as nice but by parsing the output of xrandr it’s pretty simple. So the udev rule looks like this:

SUBSYSTEM=="drm", KERNEL=="card0", ACTION=="change", RUN+="/usr/local/bin/dock.sh"

And the script I’m now using for dock/undocking my EliteBook 820 G1 on Debian 8.0 is here.

Thanks for doing me a solid past me. Well done.

on-break

awesome battery widget

I spent a few hours last night customizing the awesome window manager (wm) on my new laptop install. I’ve been using awesome for a while now (years) but I haven’t done much by way of customizing my setup. The default config from Debian, with a few small tweeks to default tags and layouts, has been sufficient. But having a battery gauge on my laptop is pretty important so I carved out a few minutes to set this up.

As always I’m not the first person to have this problem. Luckily those that came before me put their work up on github so all I had to do was clone awesome-batteryinfo, copy battery.lua into my ~/.config/awesome directory and integrate the battery widget into my rc.lua.

Integrating this widget is pretty painless. There are four steps: First you have lua pull in battery.lua:

require("battery")

Second you instantiate the widget:

mybatterywidget = widget({type = "textbox", name = "batterywidget", align = "right" })

Third you place the widget in a wibox. Debian has a wibox positioned across the top of each screen. I took the batterywidget created above and added it to the wibox widget list along side the layoutbox, textclock etc. My final mywibox.widgets looks like this:

mywibox[s].widgets = {
    {
        mylauncher,
        mytaglist[s],
        mypromptbox[s],
        layout = awful.widget.layout.horizontal.leftright
    },
    mylayoutbox[s],
    mytextclock,
    batterywidget,
    s == 1 and mysystray or nil,
    mytasklist[s],
    layout = awful.widget.layout.horizontal.rightleft
}

Finally I set up a timed event to update the widget every 20 seconds. I also seeded the widget text to show the battery data at the time the widget is created. This means that the widget will come up with meaningful data before the first even fires (20 seconds after init):

-- seed the battery widget: don't wait for first timer
mybatterywidget.text = batteryInfo("BAT0")
-- timer to update battery widget
mybatterywidget_timer = timer({timeout = 20})
mybatterywidget_timer:add_signal("timeout", function()
    mybatterywidget.text = batteryInfo("BAT0")
end)
mybatterywidget_timer:start()

That’s all there is to it. Thanks to koenwtje for the great widget. I should probably collect my awesome configs into a git repo so I don’t have to go back and rediscover how to do this every time I build a new system …