summaryrefslogtreecommitdiff
path: root/firmware/lib/vboot_api_kernel.c
diff options
context:
space:
mode:
authorLuigi Semenzato <semenzato@chromium.org>2014-01-10 16:26:08 -0800
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2014-01-19 04:14:59 +0000
commita53a0b040f45a1086515e7a5c8a8326c0b1d1f74 (patch)
tree080214e3c0574eaeac8d0e4f8e708831e3f379e7 /firmware/lib/vboot_api_kernel.c
parent46e00e63805f85c05449ce09cd843a18b76ca665 (diff)
downloadvboot-stabilize-5339.B.tar.gz
vboot: use recovery button as dev mode switch confirmationstabilize-5339.B
We don't allow ENTER from a USB keyboard as the confirmation in the switch from normal to developer mode. For devices that have a physical recovery button, we require a recovery button press instead. For other devices, we require that ENTER be pressed on the internal keyboard. This prevents an "evil keyboard" attack in which a USB keyboard (or other USB device pretending to be a keyboard) sends a control-D/ENTER sequence shortly after every boot (followed by more evil keys). In that situation, when users power-on in recovery mode, they will be forced to dev mode even if it was not their intention. Further attacks are easy at that point. TESTING. On a panther device: 1. powered on with recovery button pressed -> booted in recovery mode 2. pressed control-D on external USB keyboard -> got to ToDev? screen 3. pressed ENTER -> system beeped 4. pressed recovery button -> system rebooted in DEV mode ... all as expected Also: 1. powered on with recovery button pressed and HELD recovery button 2. pressed control-D -> system beeped BUG=chrome-os-partner:21729 TEST=manual (see commit message) BRANCH=none CQ-DEPEND=CL:182420,CL:182946,CL:182357 Change-Id: Ib986d00d4567c2d447f8bbff0e5ccfec94596aa7 Reviewed-on: https://chromium-review.googlesource.com/182241 Reviewed-by: Luigi Semenzato <semenzato@chromium.org> Tested-by: Luigi Semenzato <semenzato@chromium.org> Commit-Queue: Luigi Semenzato <semenzato@chromium.org>
Diffstat (limited to 'firmware/lib/vboot_api_kernel.c')
-rw-r--r--firmware/lib/vboot_api_kernel.c60
1 files changed, 54 insertions, 6 deletions
diff --git a/firmware/lib/vboot_api_kernel.c b/firmware/lib/vboot_api_kernel.c
index 4cf2a946..7f85dc75 100644
--- a/firmware/lib/vboot_api_kernel.c
+++ b/firmware/lib/vboot_api_kernel.c
@@ -130,26 +130,42 @@ uint32_t VbTryLoadKernel(VbCommonParams *cparams, LoadKernelParams *p,
#define CONFIRM_KEY_DELAY 20 /* Check confirm screen keys every 20ms */
-int VbUserConfirms(VbCommonParams *cparams, int space_means_no)
+int VbUserConfirms(VbCommonParams *cparams, uint32_t confirm_flags)
{
+ VbSharedDataHeader *shared =
+ (VbSharedDataHeader *)cparams->shared_data_blob;
uint32_t key;
+ uint32_t key_flags;
+ uint32_t button;
+ int rec_button_was_pressed = 0;
- VBDEBUG(("Entering %s(%d)\n", __func__, space_means_no));
+ VBDEBUG(("Entering %s(0x%x)\n", __func__, confirm_flags));
/* Await further instructions */
while (1) {
if (VbExIsShutdownRequested())
return -1;
- key = VbExKeyboardRead();
+ key = VbExKeyboardReadWithFlags(&key_flags);
+ button = VbExGetSwitches(VB_INIT_FLAG_REC_BUTTON_PRESSED);
switch (key) {
case '\r':
+ /* If we require a trusted keyboard for confirmation,
+ * but the keyboard may be faked (for instance, a USB
+ * device), beep and keep waiting.
+ */
+ if (confirm_flags & VB_CONFIRM_MUST_TRUST_KEYBOARD &&
+ !(key_flags & VB_KEY_FLAG_TRUSTED_KEYBOARD)) {
+ VbExBeep(120, 400);
+ break;
+ }
+
VBDEBUG(("%s() - Yes (1)\n", __func__));
return 1;
break;
case ' ':
VBDEBUG(("%s() - Space (%d)\n", __func__,
- space_means_no));
- if (space_means_no)
+ confirm_flags & VB_CONFIRM_SPACE_MEANS_NO));
+ if (confirm_flags & VB_CONFIRM_SPACE_MEANS_NO)
return 0;
break;
case 0x1b:
@@ -157,6 +173,20 @@ int VbUserConfirms(VbCommonParams *cparams, int space_means_no)
return 0;
break;
default:
+ /* If the recovery button is physical, and is pressed,
+ * this is also a YES, but must wait for release.
+ */
+ if (!(shared->flags & VBSD_BOOT_REC_SWITCH_VIRTUAL)) {
+ if (button) {
+ VBDEBUG(("%s() - Rec button pressed\n",
+ __func__));
+ rec_button_was_pressed = 1;
+ } else if (rec_button_was_pressed) {
+ VBDEBUG(("%s() - Rec button (1)\n",
+ __func__));
+ return 1;
+ }
+ }
VbCheckDisplayKey(cparams, key, &vnc);
}
VbExSleepMs(CONFIRM_KEY_DELAY);
@@ -505,12 +535,30 @@ VbError_t VbBootRecovery(VbCommonParams *cparams, LoadKernelParams *p)
!(shared->flags & VBSD_BOOT_DEV_SWITCH_ON) &&
(shared->flags & VBSD_BOOT_REC_SWITCH_ON) &&
VbExTrustEC()) {
+ if (!(shared->flags &
+ VBSD_BOOT_REC_SWITCH_VIRTUAL) &&
+ VbExGetSwitches(
+ VB_INIT_FLAG_REC_BUTTON_PRESSED)) {
+ /*
+ * Is the recovery button stuck? In
+ * any case we don't like this. Beep
+ * and ignore.
+ */
+ VBDEBUG(("%s() - ^D but rec switch "
+ "is pressed\n", __func__));
+ VbExBeep(120, 400);
+ continue;
+ }
+
/* Ask the user to confirm entering dev-mode */
VbDisplayScreen(cparams,
VB_SCREEN_RECOVERY_TO_DEV,
0, &vnc);
/* SPACE means no... */
- switch (VbUserConfirms(cparams, 1)) {
+ uint32_t vbc_flags =
+ VB_CONFIRM_SPACE_MEANS_NO |
+ VB_CONFIRM_MUST_TRUST_KEYBOARD;
+ switch (VbUserConfirms(cparams, vbc_flags)) {
case 1:
VBDEBUG(("%s() Enabling dev-mode...\n",
__func__));