summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--firmware/include/vboot_api.h29
-rw-r--r--firmware/lib/vboot_api_kernel.c31
-rw-r--r--tests/vboot_api_kernel6_tests.c62
4 files changed, 124 insertions, 0 deletions
diff --git a/Makefile b/Makefile
index 23916256..37ff4f7a 100644
--- a/Makefile
+++ b/Makefile
@@ -686,6 +686,7 @@ TEST_NAMES = \
tests/vboot_api_kernel3_tests \
tests/vboot_api_kernel4_tests \
tests/vboot_api_kernel5_tests \
+ tests/vboot_api_kernel6_tests \
tests/vboot_audio_tests \
tests/vboot_common_tests \
tests/vboot_common2_tests \
@@ -1365,6 +1366,7 @@ runmisctests: test_setup
${RUNTEST} ${BUILD_RUN}/tests/vboot_api_kernel3_tests
${RUNTEST} ${BUILD_RUN}/tests/vboot_api_kernel4_tests
${RUNTEST} ${BUILD_RUN}/tests/vboot_api_kernel5_tests
+ ${RUNTEST} ${BUILD_RUN}/tests/vboot_api_kernel6_tests
${RUNTEST} ${BUILD_RUN}/tests/vboot_audio_tests
${RUNTEST} ${BUILD_RUN}/tests/vboot_common_tests
${RUNTEST} ${BUILD_RUN}/tests/vboot_common2_tests ${TEST_KEYS}
diff --git a/firmware/include/vboot_api.h b/firmware/include/vboot_api.h
index 397d8840..38f94033 100644
--- a/firmware/include/vboot_api.h
+++ b/firmware/include/vboot_api.h
@@ -1028,4 +1028,33 @@ VbError_t VbVerifyMemoryBootImage(VbCommonParams *cparams,
void *boot_image,
size_t image_size);
+/**
+ * Fastboot API to enter dev mode.
+ *
+ * This routine is used by fastboot oem unlock command to switch the device into
+ * dev mode.
+ *
+ * NOTE: The caller MUST be in read-only firmware, and MUST have just obtained
+ * explicit physical confirmation from the user via a trusted input method
+ * before calling this function! Also, on successful return from this function,
+ * the caller needs to reboot the device immediately for changes to take effect.
+ *
+ * @return VBERROR_... error, VBERROR_SUCCESS on success.
+ */
+VbError_t VbUnlockDevice(void);
+
+/**
+ * Fastboot API to enter normal mode.
+ *
+ * This routine is used by fastboot oem lock command to switch the device into
+ * normal mode.
+ *
+ * NOTE: On successful return from this function, the caller needs to reboot the
+ * device immediately for changes to take effect. This routine just stores a
+ * request, which will be handled by RO firmware on next reboot.
+ *
+ * @return VBERROR_... error, VBERROR_SUCCESS on success.
+ */
+VbError_t VbLockDevice(void);
+
#endif /* VBOOT_REFERENCE_VBOOT_API_H_ */
diff --git a/firmware/lib/vboot_api_kernel.c b/firmware/lib/vboot_api_kernel.c
index f3ff3ea1..623711b9 100644
--- a/firmware/lib/vboot_api_kernel.c
+++ b/firmware/lib/vboot_api_kernel.c
@@ -1330,3 +1330,34 @@ fail:
VbExFree(kernel_subkey);
return retval;
}
+
+VbError_t VbUnlockDevice(void)
+{
+ VBDEBUG(("%s() Enabling dev-mode...\n", __func__));
+ if (TPM_SUCCESS != SetVirtualDevMode(1))
+ return VBERROR_TPM_SET_BOOT_MODE_STATE;
+
+ VBDEBUG(("%s() Mode change will take effect on next reboot.\n",
+ __func__));
+ return VBERROR_SUCCESS;
+}
+
+VbError_t VbLockDevice(void)
+{
+ VbExNvStorageRead(vnc.raw);
+ VbNvSetup(&vnc);
+
+ VBDEBUG(("%s() - Storing request to leave dev-mode.\n",
+ __func__));
+ VbNvSet(&vnc, VBNV_DISABLE_DEV_REQUEST,
+ 1);
+
+ VbNvTeardown(&vnc);
+ if (vnc.raw_changed)
+ VbExNvStorageWrite(vnc.raw);
+
+ VBDEBUG(("%s() Mode change will take effect on next reboot.\n",
+ __func__));
+
+ return VBERROR_SUCCESS;
+}
diff --git a/tests/vboot_api_kernel6_tests.c b/tests/vboot_api_kernel6_tests.c
new file mode 100644
index 00000000..42bd279c
--- /dev/null
+++ b/tests/vboot_api_kernel6_tests.c
@@ -0,0 +1,62 @@
+/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * Tests for vboot_api_kernel.c
+ */
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "test_common.h"
+#include "vboot_api.h"
+#include "vboot_nvstorage.h"
+
+/* Mock data */
+static uint32_t virtual_dev_mode_fail;
+
+/**
+ * Reset mock data (for use before each test)
+ */
+static void ResetMocks(void)
+{
+ virtual_dev_mode_fail = 0;
+}
+
+/* Mocks */
+uint32_t SetVirtualDevMode(int val)
+{
+ if (virtual_dev_mode_fail)
+ return VBERROR_SIMULATED;
+ return VBERROR_SUCCESS;
+}
+
+static void VbUnlockDeviceTest(void)
+{
+ ResetMocks();
+ TEST_EQ(VbUnlockDevice(), 0, "unlock success");
+
+ ResetMocks();
+ virtual_dev_mode_fail = 1;
+ TEST_EQ(VbUnlockDevice(), VBERROR_TPM_SET_BOOT_MODE_STATE,
+ "set dev fail");
+}
+
+static void VbLockDeviceTest(void)
+{
+ ResetMocks();
+ TEST_EQ(VbLockDevice(), 0, "lock success");
+}
+
+int main(void)
+{
+ VbUnlockDeviceTest();
+ VbLockDeviceTest();
+
+ if (vboot_api_stub_check_memory())
+ return 255;
+
+ return gTestSuccess ? 0 : 255;
+}