Commit Graph

19 Commits

Author SHA1 Message Date
Bill Richardson
b64f097891 Use the TPM to back up some of the nvram fields
We use a few bytes of battery-backed nvram to save some flags across
reboots. However if the battery discharges completely, these flags are lost.
There aren't any security issues with that since they reset to safe values,
but some of the flags are used to configure how the system boots in
dev-mode.

If a dev-mode user has completely replaced ChromeOS with some other OS, then
she often needs to set the dev_boot_usb and/or dev_boot_legacy flags as well
in order to boot it using Ctrl-U or Ctrl-L. If the battery dies, then those
flags are cleared, and the only way to make the Chromebook boot again is by
going through recovery, which wipes the disk.

This change uses a new NV space in the TPM to back up some of the nvram
flags. These nvram fields will be backed up:

  block_devmode
  dev_boot_legacy
  dev_boot_signed_only
  dev_boot_usb
  fwupdate_tries
  loc_idx

Because writing to the TPM space is slow and limited to an unspecified but
finite number of cycles, we only back up the fields when specifically
requested by the new backup_nvram_request flag. This flag will be set by
crossystem whenever it is used to change any of the fields listed above. The
backup will be attempted at the NEXT boot (because the TPM is locked after
booting), and the backup_nvram_request flag will be cleared if the backup
was successfull.

Note that this CL is for Top of Trunk only. The firmware will create the
required TPM spaces on systems that have never been booted, but we don't yet
have a secure or reliable method to update existing systems.

FYI, on Link, determining that the TPM's backup NV space doesn't exist adds
about 6ms to the boot time. If it does exist, the backup_nvram_request flag
is cleared automatically so it won't check until it's set again.

BUG=chromium:362105
BRANCH=ToT (only!)
TEST=manual

Testing this is a long and involved process. Read on...

First, there are host-side tests for it. In the chroot:

  cd src/platform/ec
  make runtests

Second, to test on a completely NEW system that was first booted with a BIOS
that contains this CL, do this:

  Enter dev-mode
  Use crossystem to set values for the fields listed above
  Confirm that "backup_nvram_request" is set to 1
  Reboot
  Use crossystem to confirm that "backup_nvram_request" is now 0
  Remove the battery and the AC
  Reattach either battery or AC so it will boot again
  Use crossystem to confirm that the backed up fields are still good, while
    the others have been reset to default values
  Switch to normal mode
  Remove the battery and the AC
  Reattach either battery or AC so it will boot again
  Look at the bios info in chrome://system to see what crossystem says
  Confirm that the dev_boot_* flags are all 0, while the others are restored

Third, to set things up to test this on an existing system (I used Link),
you have update the BIOS, delete both the Kernel and Firmware NV spaces in
the TPM, then reboot so that the BIOS will create the Backup, Kernel, and
Firmware spaces. It will only do that if they're all missing.

  Open it up, disable write-protect, attach a servo, etc.
  Switch to dev-mode, log in.
  Run make_dev_firmware.sh

  Reboot in recovery mode, and insert a USB stick with a test image on it.

  NOTE: In order to fiddle with the TPM, we'll *always* have to boot in
  recovery mode, since that's the only time the TPM is left unlocked. That's
  NOT the same as pressing Ctrl-U at the scary boot screen. The rest of
  these steps assume you've booted in recovery mode and are running from the
  test image on the USB stick.

  Run

    make_dev_ssd.sh --remove_rootfs_verification --recovery_key

  Reboot (recovery mode)

  Run

    mv /etc/init/tcsd.conf /etc/init/tcsd.conf.disabled

  Reboot (recovery mode).

  Run "tpmc getvf". It should say

    deactivated 0
    disableForceClear 0
    physicalPresence 1
    physicalPresenceLock 0
    bGlobalLock 0

  Run "tpmc geto". It should say

    Owned: no

  Now you'll need to build the "tpm-nvtool" utility. In the chroot:

    cd src/third_party/tpm/nvtool
    make

  Copy that to the DUT, in /usr/local/bin.

  Now run

    tcsd
    tpm-nvtool --list | grep Index

  You may see a number of spaces, but you should at least see these:

     # NV Index 0x00001007
     # NV Index 0x00001008

  Run

    tpm_takeownership

  It will prompt you for two passwords (and confirm each one). Respond with
  something you can remember like "google".

  Run

    tpm-nvtool  --release --index 0x1007 --owner_password "google"
    tpm-nvtool  --release --index 0x1008 --owner_password "google"

  Verify that it worked with

    tpm-nvtool --list | grep Index

  Power off.

  Using servo, flash the new BIOS that has this CL in it.

  Power on, normally this time (not recovery mode). If all goes well, it
  should create the correct NV spaces and boot into the SSD. Copy tpm-nvtool
  into this image too, and run

    tpm-nvtool --list | grep Index

  You should now see at least these spaces:

     # NV Index 0x00001007
     # NV Index 0x00001008
     # NV Index 0x00001009

  Now you're ready to test the backup/recover feature.

Change-Id: I00031fa0774720147327e2ae0f37e26b34b86341
Signed-off-by: Bill Richardson <wfrichar@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/202138
Reviewed-by: Luigi Semenzato <semenzato@chromium.org>
2014-06-05 23:15:39 +00:00
Simon Glass
527ba810ef Implementation of Region API
At present reading data from storage in Vboot is a little fragmented. For
the firmware image, we expect the boot loader to handle this. For the disk
we have a block-level API. For the GBB (which also sits in the firmware
image) we expect the entire thing to be read before Vboot is called.

Add the concept of a region, and an API to read from a region. At present,
and most pressing, is reading from a GBB region. In the future this could
be extended to other parts of the firmware or even the disk.

Move all access to the GBB into this API so that the boot loader can provide
either a GBB region in one large contiguous chunk, or a function to deal with
read requests from vboot.

The call to VbExRegionRead() is behind a flag since not all boot loaders
support it yet.

The main change for boot loaders which don't support this new API is that
vboot will do more behind the scenes. For example, it will allocate memory
for chunks of data that it reads from the GBB, rather than just accessing it
directly. This approach is considerably simpler than trying to pass char **
everywhere and have vboot decide whether something needs to be allocated or
not.

The tests are updated, mainly to include setting up a GBB structure
accessible from VbCommonParams, which is now required by the firmware and
kernel functions. In normal operation this is set up at the start of
VbLoadFIrmware() and VbSelectAndLoadKernel() but for tests which call
children of these functions directly, the GBB structure must be set up
manually by the test.

BUG=chrome-os-partner:21115
BRANCH=none
TEST=manual
FEATURES=test sudo -E  emerge vboot_reference

Change-Id: If2b8bbe467fdbd643239d8d9b5d7aa98df4d286f
Signed-off-by: Simon Glass <sjg@chromium.org>
Signed-off-by: David Hendricks <dhendrix@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/63336
Reviewed-by: Randall Spangler <rspangler@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/167361
2013-08-30 16:47:03 +00:00
Yoshiki Iguchi
8fa13ad6f7 Revert "Implementation of Region API"
This reverts commit 1d3c804b6b.

This patch breaks cbuildbot on internal paladins bots.

Change-Id: Icf7f9d9bbb56b092035888eaa3e249ffd23fac16
(cherry picked from commit 3a60335ebb1530e5fd9d5da3bc6214949bc59caf)
Reviewed-on: https://chromium-review.googlesource.com/167451
Reviewed-by: Yoshiki Iguchi <yoshiki@chromium.org>
Commit-Queue: Yoshiki Iguchi <yoshiki@chromium.org>
Tested-by: Yoshiki Iguchi <yoshiki@chromium.org>
2013-08-29 05:36:12 +00:00
Simon Glass
1d3c804b6b Implementation of Region API
At present reading data from storage in Vboot is a little fragmented. For
the firmware image, we expect the boot loader to handle this. For the disk
we have a block-level API. For the GBB (which also sits in the firmware
image) we expect the entire thing to be read before Vboot is called.

Add the concept of a region, and an API to read from a region. At present,
and most pressing, is reading from a GBB region. In the future this could
be extended to other parts of the firmware or even the disk.

Move all access to the GBB into this API so that the boot loader can provide
either a GBB region in one large contiguous chunk, or a function to deal with
read requests from vboot.

The call to VbExRegionRead() is behind a flag since not all boot loaders
support it yet.

The main change for boot loaders which don't support this new API is that
vboot will do more behind the scenes. For example, it will allocate memory
for chunks of data that it reads from the GBB, rather than just accessing it
directly. This approach is considerably simpler than trying to pass char **
everywhere and have vboot decide whether something needs to be allocated or
not.

The tests are updated, mainly to include setting up a GBB structure
accessible from VbCommonParams, which is now required by the firmware and
kernel functions. In normal operation this is set up at the start of
VbLoadFIrmware() and VbSelectAndLoadKernel() but for tests which call
children of these functions directly, the GBB structure must be set up
manually by the test.

BUG=chrome-os-partner:21115
BRANCH=none
TEST=manual
FEATURES=test sudo -E  emerge vboot_reference

Change-Id: I2c19e9dc2ed602d0642bbf4f7d27f79fe9fad873
Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/63336
Reviewed-by: Randall Spangler <rspangler@chromium.org>
2013-08-28 18:30:35 +00:00
Shawn Nematbakhsh
472d93c146 rollback_index: Remove recovery_mode parameter to SetupTPM.
SetupTPM no longer uses recovery_mode parameter for anything other than
a debug print. This change moves the debug print to a caller function,
then removes recovery_mode from SetupTPM and some caller functions that
no longer have a use for it.

BUG=chrome-os-partner:20913.
TEST=Manual. Boot factory install shim in recovery mode and verify TPM
clear operations succeed. Boot in dev mode and verify "Lock physical
presence" print on UART.
BRANCH=None.

Signed-off-by: Shawn Nematbakhsh <shawnn@chromium.org>
Change-Id: I2f671f6680a6e67cf722855e659e99752bc0783c
Reviewed-on: https://gerrit.chromium.org/gerrit/62916
Reviewed-by: Randall Spangler <rspangler@chromium.org>
2013-07-23 12:37:04 -07:00
Bill Richardson
0c3ba249ab Massive refactoring of external header files.
This reduces the number of exported header files to the minimum needed by
the existing userspace utilities and firmware implementations.

BUG=chromium:221544
BRANCH=none
TEST=manual, trybots
CQ-DEPEND=CL:47019,CL:47022,CL:47023

  sudo FEATURES=test emerge vboot_reference
  FEATURES=test emerge-$BOARD \
                vboot_reference \
                chromeos-cryptohome \
                chromeos-installer \
                chromeos-u-boot \
                peach-u-boot \
                depthcharge

Change-Id: I2946cc2dbaf5459a6c5eca92ca57d546498e6d85
Signed-off-by: Bill Richardson <wfrichar@chromium.org>
Reviewed-on: https://gerrit.chromium.org/gerrit/47021
Reviewed-by: Randall Spangler <rspangler@chromium.org>
2013-04-02 14:12:52 -07:00
Gabe Black
ac8805e7e9 Get rid of some crufty macros.
These were macros that were never used, or that were only set to one thing and
could be substituted up front.

I left in code guarded by the HAVE_ENDIAN_H and HAVE_LITTLE_ENDIAN macros even
though those are never defined because they guard a reportedly significantly
faster implementation of some functionality, at least according to a comment
in the source. It would be a good idea to enable that code path and see if it
really does make a big difference before removing it entirely.

BUG=None
TEST=Built for Link, Daisy, and the host with FEATURES=test. Built depthcharge
for Link and booted in normal mode.
BRANCH=None

Change-Id: I934a4dd0da169ac018ba07350d56924ab88b1acc
Signed-off-by: Gabe Black <gabeblack@google.com>
Reviewed-on: https://gerrit.chromium.org/gerrit/45687
Reviewed-by: Randall Spangler <rspangler@chromium.org>
Commit-Queue: Gabe Black <gabeblack@chromium.org>
Tested-by: Gabe Black <gabeblack@chromium.org>
2013-03-19 16:55:44 -07:00
Randall Spangler
723aed378c Improve coverage of vboot_api_init.c
BUG=chromium-os:38139
BRANCH=none
TEST=make runtests

Change-Id: I3d39feb712eb7e572f9c57f27449f19e8e809ed0
Reviewed-on: https://gerrit.chromium.org/gerrit/41896
Commit-Queue: Randall Spangler <rspangler@chromium.org>
Reviewed-by: Randall Spangler <rspangler@chromium.org>
Tested-by: Randall Spangler <rspangler@chromium.org>
2013-01-24 15:39:14 -08:00
Randall Spangler
1cbf705405 Reformat vboot_api_init_tests
No code changes, just reformat to kernel style

BUG=none
BRANCH=none
TEST=make runtests

Change-Id: I9b07af36b915ead519a8908b3dc5b93aedc5d4be
Signed-off-by: Randall Spangler <rspangler@chromium.org>
Reviewed-on: https://gerrit.chromium.org/gerrit/41895
Reviewed-by: Bill Richardson <wfrichar@chromium.org>
2013-01-24 08:32:19 -08:00
Bill Richardson
640b1c4207 Add more recovery_reason codes
There are several places where the same recovery_reason was used to report
slightly different points of failure. Let's create some new codes instead.

Remember that recovery mode is handled by RO firmware, so if an updated RW
firmware uses one of the new error codes, pressing TAB at the recovery
screen will say "We have no idea what this means". That's not a bug. This CL
deprecates the original codes, so the fact that the RO firmware doesn't
recognize it just means it's a new code reported by a new RW BIOS.

BUG=chromium-os:36562
TEST=manual
BRANCH=parrot

Run

  make && make runtests

It should pass. You can test some of the error cases on actual hardware by
using

  crossystem recovery_reason=86
  reboot

and pressing TAB at the recovery screen. For that example you should see the
message

  recovery_reason: 0x56 TPM lock error in rewritable firmare

Change-Id: I123c781e6c6f6fe0284c4fd49f5f5a855eece7df
Reviewed-on: https://gerrit.chromium.org/gerrit/38652
Commit-Ready: Bill Richardson <wfrichar@chromium.org>
Tested-by: Bill Richardson <wfrichar@chromium.org>
Reviewed-by: Randall Spangler <rspangler@chromium.org>
2012-11-26 12:04:42 -08:00
Bill Richardson
9dc62178c9 Add VB_INIT_FLAG_SW_WP_ENABLED to VbInit() input flags.
We need to know not only whether the HW WP pin is asserted, but whether the
flash chip has configured its software protection registers to actually
protect anything. This flag can be used to indicate that.

BUG=chrome-os-partner:13265
BRANCH=link
TEST=none

This just adds the flag. Nothing actually sets the flag yet, so there's
nothing to test.

Change-Id: Icba9945fb56eb3a4681486c630cbbdc9232485ef
Signed-off-by: Bill Richardson <wfrichar@chromium.org>
Reviewed-on: https://gerrit.chromium.org/gerrit/31642
Reviewed-by: Randall Spangler <rspangler@chromium.org>
2012-08-28 16:39:33 -07:00
Randall Spangler
29e8807ea0 Add clear TPM owner request
This adds two new flags to crossystem:
   clear_tpm_owner_request
   clear_tpm_owner_done

The first one requests that the firmware clear the TPM owner on the
next boot.  When the firmware does this, it will set
clear_tpm_owner_request=0, and set clear_tpm_owner_done=1.  The OS can
use the done-flag as a hint that trusted things guarded by the TPM are
no longer trustable.

BUG=chromium-os:31974
TEST=manual

crossystem
  // both flags initially 0
crossystem clear_tpm_owner_request=1
crossystem clear_tpm_owner_done=1
  // request=1, done=0; done can be cleared but not set by crossystem
reboot
tpmc getownership
  // owned=no
crossystem
  // request=0, done=1
crossystem clear_tpm_owner_done=0
crossystem
  // both flags 0 again

Signed-off-by: Randall Spangler <rspangler@chromium.org>
Change-Id: I49f83f3c39c3efc3945116c51a241d255c2e42cd
Reviewed-on: https://gerrit.chromium.org/gerrit/25646
2012-08-15 14:31:53 -07:00
Bill Richardson
45de9c931b Fix broken tests left from commit dc6b642b
BUG=chrome-os-partner:10947
TEST=manual

make && make runtests

Change-Id: Idd5e10fc0cfed059f035d127f06ca009f0cff03a
Signed-off-by: Bill Richardson <wfrichar@chromium.org>
Reviewed-on: https://gerrit.chromium.org/gerrit/27124
Reviewed-by: Randall Spangler <rspangler@chromium.org>
2012-07-10 21:52:12 -07:00
Randall Spangler
acd6f4688a Add GBB flags to enable dev mode by default
And enable dev_boot_usb by default.
And disable rollback checks.

The first flag is necessary for factory to build with keyboard
controlled dev mode.  The other flags are really handy for development
on systems where you've defeated firmware WP and are installing custom
firmware.

BUG=chromium-os:31844
TEST=make && make runtests

Signed-off-by: Randall Spangler <rspangler@chromium.org>

Change-Id: I9d837fee676cb0186ea98f13005ad60a9ab86393
Reviewed-on: https://gerrit.chromium.org/gerrit/25265
Tested-by: Randall Spangler <rspangler@chromium.org>
Reviewed-by: Bill Richardson <wfrichar@chromium.org>
Reviewed-by: Hung-Te Lin <hungte@chromium.org>
Commit-Ready: Randall Spangler <rspangler@chromium.org>
2012-06-14 18:57:52 -07:00
Bill Richardson
ec8df1628c Support virtual dev-switch (keyboard-based dev-mode)
BUG=chrome-os-partner:9706
TEST=manual

Currently, Link is the only platform that enables this feature.

To enter dev-mode:

  Boot into recovery mode using the magic key chord. At the Insert screen,
  press Ctrl-D. You'll be asked if you want to enter developer mode. If you
  then press ENTER, it will reboot with dev-mode enabled. If you press SPACE
  or ESC, it will return to the Insert screen.

  If you enter recovery mode through any other means, or if dev-mode is
  already enabled, pressing Ctrl-D at the Insert screen will have no effect.

To return to normal mode:

  Reboot. At the Dev screen, press ENTER or SPACE. It will reboot to
  recovery mode and ask you if you want to return to normal mode. If you
  press ESC or power off, you'll still be in dev-mode. Press ENTER or SPACE,
  and it will reboot into normal mode (of course, if you've messed up your
  images while in dev-mode, you'll just come right back to recovery mode
  again).

  You can also request a direct return to normal mode by running

    crossystem disable_dev_request=1

  and rebooting.

Change-Id: I435905855a6c39932ee466cc046bdc4c4c860f98
Reviewed-on: https://gerrit.chromium.org/gerrit/24160
Tested-by: Bill Richardson <wfrichar@chromium.org>
Reviewed-by: Bill Richardson <wfrichar@chromium.org>
Commit-Ready: Bill Richardson <wfrichar@chromium.org>
2012-06-08 22:24:05 -07:00
Bill Richardson
b75d8adcc0 Use virtual dev-mode switch when told to.
If VbInit() is instructed to look at a virtual dev-mode switch, then it will
use value contained in the TPM's firmware space instead of a hardware GPIO
to determine if developer mode is enabled.

This change just makes it look. It doesn't provide a way to actually set
the value in the TPM. VbInit() isn't being told to look yet, either. Those
changes are coming.

BUG=chrome-os-partner:9706
TEST=none

The usual sanity-check applies:

  make
  make runtests

But to actually test that this stuff is working IRL requires special tweaks
to other components and monitoring the serial debug output from both EC and
CPU. We'll save the hands-on tests for when it's all done.

Change-Id: Ie485ad2180224e192238bf2a5dbf95bbcb9130f9
Signed-off-by: Bill Richardson <wfrichar@chromium.org>
Reviewed-on: https://gerrit.chromium.org/gerrit/23067
Reviewed-by: Randall Spangler <rspangler@chromium.org>
2012-05-18 18:15:58 -07:00
Bill Richardson
7272a69511 Dev-mode allows booting self-signed kernels by default.
When you enter dev-mode,

  Pressing Ctrl-U to boot from USB is DISABLED.
  Booting any self-signed kernel from the SSD is ENABLED.

This replaces the "crossystem dev_boot_custom" argument with
"crossystem dev_boot_signed_only", which has the opposite polarity.
So if you want to dev-mode to only boot official kernels, you have to
explictly set it that way. If you leave dev-mode and then come back,
it will go back to the conditions shown above.

BUG=chrome-os-partner:5954
TEST=manual

Just run the factory flow. It was broken; this should fix it (except for any
workarounds that were added while it was broken; those may need to be
reverted).

Change-Id: I13e0edbc0e77c5d6ea609dabf771085006cd1805
Reviewed-on: https://gerrit.chromium.org/gerrit/11853
Reviewed-by: Hung-Te Lin <hungte@chromium.org>
Tested-by: Hung-Te Lin <hungte@chromium.org>
Reviewed-by: Stefan Reinauer <reinauer@chromium.org>
2011-11-18 13:39:37 -08:00
Bill Richardson
c8e4ff7c15 Add flag to GBB to allow loading PCI Option ROMs
As shipped, H2C only loads the option ROM for the built-in video, and that
only when it needs display the BIOS warning screens.

By setting a flag in the GBB, you can allow all option ROMs to be loaded:

Note that we'll never enable this ourselves (and there's a factory test to
ensure that*) because it executes non-verified code. But if a customer wants
to void their warranty and set this flag in the read-only flash so they can
install and use other PCI devices, they should be able to do so.

BUG=chrome-os-partner:6148
TEST=none

The only way to test this is to use a BIOS that was compiled with serial
debugging enabled, so there's nothing for QA to do. If you have such a BIOS,
you can see the difference like so:

  flashrom -r oldbios.bin
  gbb_utility -s --flags=2 oldbios.bin newbios.bin
  flashrom -w newbios.bin
  <reboot>

When bit 1 of the GBB flags is 0, you'll see these lines in the serial
output:

  LoadOpRomImage-->GetSystemConfigurationTable Status = Success
  LoadOpRomImage-->GetH2cBootMode Status = Success

When bit 1 of the GBB flags is 1, you'll see these lines in the serial
output:

  LoadOpRomImage-->GetSystemConfigurationTable Status = Success
  LoadOpRomImage-->GetH2cBootMode Status = Success
  LoadOpRomImage-->PCI OpRom on 1.0.0 is allowed!!!

This happens in any boot mode (normal, developer, recovery).

--
*The factory test for GBB zero flags is gft_clear_gbb_flags.sh, in
 src/platform/factory_test_tools

Change-Id: I31a10cc9d562b4b83669ca8a114b60e87ae28b0a
Reviewed-on: https://gerrit.chromium.org/gerrit/11505
Tested-by: Bill Richardson <wfrichar@chromium.org>
Reviewed-by: Gaurav Shah <gauravsh@chromium.org>
Reviewed-by: Randall Spangler <rspangler@chromium.org>
2011-11-11 11:01:20 -08:00
Randall Spangler
391b31024d Add unit tests for vboot_api_init.c
BUG=chromium-os:17564
TEST=make && make runtests

Change-Id: Idca158e82d1ea102221ea3b51d445fadee9d2794
Reviewed-on: http://gerrit.chromium.org/gerrit/7183
Reviewed-by: Luigi Semenzato <semenzato@chromium.org>
Tested-by: Randall Spangler <rspangler@chromium.org>
2011-09-06 14:05:03 -07:00