Ticket #9045 (closed defect: fixed)

Opened 6 years ago

Last modified 4 years ago

XO-1: key delegation

Reported by: kimquirk Owned by: wmb@…
Priority: normal Milestone: 1-firmware-security
Component: security Version: not specified
Keywords: cjbfor9.1.0 8.2.1:+ Cc: wmb@…, wad, mstone, edmcnierney, dsd, cscott, reuben
Action Needed: no action Verified: no
Deployments affected: Uruguay Blocked By:
Blocking:

Description

Uruguay request.

They need a way to sign their own builds: http://wiki.laptop.org/go/Firmware_Key_and_Signature_Formats#Version_2

Attachments

patch1.txt (8.9 kB) - added by dsd 6 years ago.
first attempt (untested)
0001-Read-multiple-deployment-keys-from-OFW.patch (5.8 kB) - added by dsd 5 years ago.
leases patch
0001-Import-bitfrost.leases.keys-while-OFW-is-available.patch (1.7 kB) - added by dsd 5 years ago.
olpcrd patch
rd.zip (2.6 MB) - added by dsd 5 years ago.
rd.zip
s1.public (270 bytes) - added by dsd 5 years ago.
public key for rd.zip signature

Change History

  Changed 6 years ago by cscott

  • cc wmb@…, wad, mstone, edmcnierney added

This bug needs further design and review.

The v2 signature mechanism requires a unique signature file per machine serial number. This is reasonable for activation leases and developer keys (the design goal), but doesn't fit the current build reflashing procedure well: there would need to be a different fs.zip, in effect, for each machine you reflashed. You could probably combine the keys for, say, up to 1k machines in a single fs.zip, but delegated signatures for 15k machines may well be impractical. The relevant metrics are: how large is the signature (ie, does it prevent the build + signature from fitting on a reasonable sized key), and how much time is added to the reflash procedure by having to scan through a large number of signatures looking for the 'right' one.

One might extend the delegation mechanism to support wildcard serial numbers, which might make the leases more compact under some circumstances. Or you could key delegation on some other property other than serial number, like the LOC tag -- but this would require Quanta to start adding this tag to the XO's mfg-data (currently it's in Quanta's database which is sent to us, but not actually written to the XO), and would complicate "repurposing" efforts if, say, G1G1 machines were diverted to Uruguay.

It may be better just to give Uruguay custom firmware with their own key pairs and be done with it. Michael Stone reports that Uruguay is excited about building their own firmware, kernels, and initramfs and hacking on security themselves. We can't afford to maintain or support their changes in this case anyway, we might as well just cut them free. There may be legal implications wrt our ability to satisfy developer key requests.

  Changed 6 years ago by mstone-xmlrpc

  • keywords cjbfor9.1.0 added
  • milestone changed from 8.2.1 to 9.1.0

Pushing out to 9.1.0, per edmcnierney's request.

  Changed 6 years ago by cscott

  • keywords cjbfor9.1.0 removed
  • milestone changed from 9.1.0 to 8.2.1

  Changed 6 years ago by mstone-xmlrpc

  • keywords cjbfor9.1.0 added
  • milestone changed from 8.2.1 to 9.1.0

Pushing out to 9.1.0, per edmcnierney's request.

  Changed 6 years ago by mstone

  • next_action changed from never set to design
  • milestone changed from 9.1.0 to 8.2.1

As cjb says, this is on the shortlist. Some day, I'll write a smarter script. :)

As scott says, this needs design-work.

  Changed 6 years ago by edmcnierney

  • keywords 8.2.1:+ added

  Changed 6 years ago by cjb

  • owner changed from cscott to wmb@…
  • next_action changed from design to code

  Changed 6 years ago by mstone

  • next_action changed from code to test in build

This is available in staging-25; see http://wiki.laptop.org/go/Firmware_security#Multiple-Key_Support for details.

So far, I've tested the firmware key override ('w0') and OS key augmentation ('o1'). I'm satisfied by both.

(Side request -- could someone add a CLI verification tool for the sig01-format sigs to http://dev.laptop.org/git/bios-crypto? Thanks!)

  Changed 6 years ago by mstone

Second side request: someone (maybe me, if I get ambitious) needs to patch http://dev.laptop.org/git/users/cscott/olpcrd-rootskel to read the new key overlay data so that we can actually activate laptops with alternate keys.

  Changed 6 years ago by dsd

  • cc dsd added

  Changed 6 years ago by dsd

Re activating laptops with alternate keys: I took a quick look and it looks like olpcrd-rootskel does not actually work with keys. That part is done with bitfrost.leases.* which currently hardcodes the single-accepted lease key in bitfrost.leases.keys (it does not read from OFW). I guess that is the module that needs to be changed, but I'm not sure which package the code comes from and what is responsible for stuffing it into the initrd (or does it read it from root?)

  Changed 6 years ago by cjb

  • next_action changed from test in build to code

Setting this one back to "code", to cover the necessary initrd changes. Dan and Michael, would be awesome if you could work together on this.

I guess the first step is to come up with a patch to the leases module (git://dev.laptop.org/users/cscott/leases) and then we can figure out how to rebuild the initrd to contain it. (Just unpacking the current initrd and putting the modified code in may turn out to be a reasonable plan.)

Changed 6 years ago by dsd

first attempt (untested)

  Changed 6 years ago by dsd

I attached an initial attempt at the code modifications. Some considerations and questions:

  • The /ofw path that I am reading from is probably wrong
  • I guess the /ofw key data will be binary, so we probably need code to reformat it in the textual format.
  • are there any users of DEVELOPER_KEYS, LEASE_KEYS, etc outside of this module? If so I have broken some API...
  • Is /ofw mounted at the time that get_lease_keys() is called? If not, where should we mount it from?

  Changed 6 years ago by dsd

Scott suggests leaving the variable names alone and adding some inline code (to execute upon import) which modifies the lists accordingly (including removing the OLPC key if the x0 key is there).

w.r.t. availability of /ofw: "put 'import bitfrost.leases.keys' as the last line in the try block in init.py after 'if xo' and before 'umount /ofw' - line 53 of init"

  Changed 6 years ago by cscott

From irc log:

(01:51:29 PM) C. Scott Ananian: all the lease checking stuff comes from the 'leases' package in git
(01:52:10 PM) C. Scott Ananian: which is a submodule of both olpc-update and rootskel
(01:52:50 PM) C. Scott Ananian: you'll find it in rootskel/src-olpc/leases
(01:52:52 PM) cjb: cscott: would be great if you could comment on our approach at the bottom of http://dev.laptop.org/ticket/9045
(01:53:33 PM) C. Scott Ananian: dsd's patch1 seems overly complicated
(01:54:03 PM) C. Scott Ananian: FW_KEYS (etc) is not *supposed* to be OLPC_FW_KEYS
(01:54:11 PM) C. Scott Ananian: it is supposed to be the list of valid FW_KEYS
(01:54:25 PM) C. Scott Ananian: there isn't any need for a get_keys() function
(01:54:49 PM) dsd_: in that case we now need some code to run when the module is imported though, right?
(01:54:58 PM) C. Scott Ananian: dsd_: yes, that's the Python Way.
(01:55:17 PM) dsd_: would we do that by having code inline (not in functions) in the file?
(01:55:28 PM) C. Scott Ananian: dsd_: that's how python does it
(01:55:51 PM) C. Scott Ananian: something like:
(01:56:02 PM) C. Scott Ananian: FW_KEYS = [ 'asdasdasdasda....' ]
(01:56:23 PM) C. Scott Ananian: if (exists('ofw/fw')) FW_KEYS += [ read_key('ofw/fw') ]
(01:56:38 PM) C. Scott Ananian: would probably be sufficient.
(01:57:10 PM) C. Scott Ananian: instead of 'if exists' you'd probably want to encapsulate that in a function that does the proper replace/augment logic; i don't know exactly how Mitch_Bradley chose to implement that.
(01:56:46 PM) dsd_: are there users of FW_KEYS that you know of?
(01:57:22 PM) C. Scott Ananian: dsd_: not yet.
(01:58:07 PM) dsd_: any idea about the availability of /ofw at that point in time?
(01:58:56 PM) C. Scott Ananian: put 'import bitfrost.leases.keys' as the last line in the try block in init.py after 'if xo'
(01:59:05 PM) C. Scott Ananian: and before 'umount /ofw'
(01:59:42 PM) C. Scott Ananian: line 53 of init
(01:59:41 PM) m_stone: the irfs (and also olpc-update on the nand) uses an additional key sequence called the OATS_KEY to authenticate messages that we receive when running the theft-deterrence protocol.
(02:00:24 PM) dsd_: cscott: one other point.. in some cases we have to *remove* the OLPC key from the list. does that change your opinion on code layout? or would we initialise it as-is and then remove immediately after?
(02:00:35 PM) C. Scott Ananian: FW_KEY = [ ... ]
(02:00:49 PM) C. Scott Ananian: update_from_ofw(FW_KEY)
(02:01:03 PM) C. Scott Ananian: OATS_KEY = [...]
(02:01:08 PM) C. Scott Ananian: update_from_ofw(OATS_KEY)
(02:01:29 PM) C. Scott Ananian: the update_from_ofw function is probably misnamed
(02:01:41 PM) C. Scott Ananian: as m_stone points out, OATS and some of the other keys aren't really OFW-specific
(02:01:51 PM) C. Scott Ananian: i'm just encouraging a consistent override mechanism.
(02:02:19 PM) C. Scott Ananian: actually, i lied: i like the update_from_ofw name
(02:02:40 PM) C. Scott Ananian: given the naming scheme in use, you can probably write mfg-data to override the OATS key and others as well
(02:03:08 PM) C. Scott Ananian: but if you like, you can have update_from_ofw also check /etc/key-overrides/xyz (if it exists) as well.
(02:03:31 PM) C. Scott Ananian: that won't exist in the initrd, but it could perhaps exist in the root filesystem, where olpc-update could see it.
(02:04:47 PM) Mitch_Bradley: the logic in ofw is the forth equivalant of   list =  ( (exists tag x0) ? tag x0 : olpc x key) + tag x1 + tag x2 + ... tag x9
(02:06:06 PM) dsd_: in that case we have to assign a new naming scheme for oats keys
(02:06:14 PM) dsd_: currently we have
(02:06:16 PM) dsd_:    1.  Developer key - tag names d0 .. d9 (d for developer)
(02:06:16 PM) dsd_:    2. Firmware key - tag names w0 .. w9 (w for firmWare)
(02:06:16 PM) dsd_:    3. Filesystem key - tag names s0 .. s9 (s for fileSystem)
(02:06:16 PM) dsd_:    4. OS key - tag names o0 .. o9 (oh for OS)
(02:06:18 PM) dsd_:    5. Activation lease key - tag name a0 .. a9 (a for activation) 
(02:06:35 PM) m_stone: dsd_: I suggest 't0 -- t9' for "theft"
(02:06:55 PM) C. Scott Ananian: or u0-u9 for "update/upgrade"
(02:07:04 PM) m_stone: cscott: yes, that might be even better.
(02:07:18 PM) m_stone: whoever implements it gets to pick their favorite. :)

  Changed 6 years ago by dsd

I have completed one part of mitch's test plan (http://wiki.laptop.org/go/Firmware_security#Test_Plan), where device=usb and X=s. No problems found. This is a time consuming process so I would appreciate it if someone else wants to take one of the values for X.

I am doing device=usb X=o next.

  Changed 6 years ago by dsd

clarification, I am currently doing device=usb X=w ..

X=o is up for grabs

  Changed 6 years ago by dsd

device=usb X=w : success

  Changed 5 years ago by dsd

device=nand X=a : success

(no other devices are valid here, the lease is only searched for on NAND)

  Changed 5 years ago by dsd

device=usb X=o : success

  Changed 5 years ago by dsd

device=usb X=d : success

That's all of them, at least for USB. I don't have any SD cards but I am going to repeat some selected tests using the NAND instead.

  Changed 5 years ago by dsd

Additional tests performed:

  1. Added an augment key for developer keys, created my own develop.sig, put it on the NAND and confirmed that it unsecured the machine.
  2. Added a firmware augment key, signed my own Q2E30, put it on the NAND, booted and watched it attempt to upgrade from Q2E29 to Q2E30 (it did not do the upgrade, as I had intentionally removed the battery, but it did trust the signature)
  3. Created an augment key for OS, resigned the staging-25 kernel with my own key, put it on the NAND and confirmed that it booted.

I also did the miscellanous tests suggested by Mitch: Test the ability to install and remove keys from mfg data - create several new keys, both augment and override. Delete and recreate in various orders. Check attempts to create keys that already exist, deleting the last key, etc. Verify that the mfg data looks correct after each operation.

Check the visibility of the keys from Linux (in /mfg-data).

No problems found.

This concludes my testing, unless anyone has any suggestions for more. Someone may want to test from a SD card. Otherwise I think we can say that the OFW part works perfectly!

Changed 5 years ago by dsd

leases patch

Changed 5 years ago by dsd

olpcrd patch

  Changed 5 years ago by dsd

  • next_action changed from code to review

Posted patches for leases and olpcrd. Please review.

I have run some basic tests for status-quo, override, and augment setups. It is working. I will apply something similar to Mitch's full test plan to these components when this makes it into a build.

follow-up: ↓ 25   Changed 5 years ago by mstone

  • cc cscott added

The patches look good to my thirty-second inspection. Scott?

in reply to: ↑ 24   Changed 5 years ago by cscott

Replying to mstone:

The patches look good to my thirty-second inspection. Scott?

Looks good to me, too. It may be worth double-checking that olpc-update with the patched leases submodule works correctly (although I can't see any reason why it would not). But looks like great work from dsd, as usual. ;-)

  Changed 5 years ago by cjb

  • next_action changed from review to package

Given Scott's +1, this is ready for packaging.

Daniel, I suggest just patching the files in-place and repacking the initrd archive afterwards, for the moment, and I'll work on getting a Debian VM available to properly rebuild the initrd.

Since this is the last bug we know we need to fix, we can make our first candidate build once this packaging's done.

  Changed 5 years ago by dsd

I have a rd.zip including my changes which is how I did my testing. However, I don't know how I could insert that into the build outside of the usual packaging route, and I'm also not sure that it's worth it: given the complexity of testing this feature, I think I should just provide that file to any interested parties (reuben, and maybe you?)

Packaging should not be that hard, we just need a working debian install. There are clear instructions here which could probably be done by anyone: http://wiki.laptop.org/go/Building_initramfsen

I wouldn't know, but it can't be *that* hard to install debian, right? ;) I would do it here except it would take days to download...

  Changed 5 years ago by reuben

  • cc reuben added

dsd, could you attach it to the bug for testing.

Changed 5 years ago by dsd

rd.zip

Changed 5 years ago by dsd

public key for rd.zip signature

  Changed 5 years ago by dsd

Done. Attached a signed rd.zip, and the public key for verifying the signature.

Load the key into (e.g.) o1 and put rd.zip in /versions/boot/current/boot

  Changed 5 years ago by reuben

Tested attached rd.zip with OLPC Master (no keys), a1, a0, a0+a1, a0+a1+a2. Activation was done via USB, SD, and WiFi in all cases.

  Changed 5 years ago by dsd

  • next_action changed from package to test in build

olpcrd-0.50-0.i386.rpm is ready for next staging build

  Changed 5 years ago by dsd

that one had wrong leases submodule version, olpcrd-0.51 queued for next build...

  Changed 5 years ago by dsd

  • next_action changed from test in build to finalize

I ran Mitch's test plan (using device=usb) against 8.2.1-800, this time checking the initramfs-level behaviour for activation. Works fine.

  Changed 5 years ago by wmb@…

  • status changed from new to assigned

svn 1336 adds OFW support for sig02: style key delegation. Deployment in an official release is pending extensive testing in brown-bag releases.

  Changed 5 years ago by wmb@…

  • summary changed from key delegation to XO-1: key delegation

  Changed 5 years ago by wmb@…

  • next_action changed from finalize to add to release

  Changed 5 years ago by wmb@…

  • priority changed from high to normal

  Changed 5 years ago by wmb@…

  • milestone changed from 8.2.1 to Future Release

  Changed 5 years ago by wmb@…

  • milestone changed from Future Release to 1.0-firmware-security

  Changed 4 years ago by wmb@…

  • next_action changed from add to release to test in release

Test in Q2E42

  Changed 4 years ago by wmb@…

  • status changed from assigned to closed
  • next_action changed from test in release to no action
  • resolution set to fixed

Martin says it is okay to close this.

Note: See TracTickets for help on using tickets.