mount-encrypted: support static key factory mode

For factory images, we want to be able to retain /var across reboots
without interacting with the TPM, and ultimately hold the test suite
in a pre-built image so we can avoid needing to wipe the entire
filesystem when switching modes.

BUG=chrome-os-partner:11392, chrome-os-partner:9419
TEST=link build, manual testing

Change-Id: I58aab24455670697e3df494632d5105dde75ee85
Signed-off-by: Kees Cook <keescook@chromium.org>
Reviewed-on: https://gerrit.chromium.org/gerrit/27793
Reviewed-by: Gaurav Shah <gauravsh@chromium.org>
Reviewed-by: Jon Salz <jsalz@chromium.org>
This commit is contained in:
Kees Cook
2012-07-18 11:29:39 -07:00
committed by Gerrit
parent 9ed5fedc6b
commit 0c66fee704

View File

@@ -56,6 +56,10 @@ static const uint32_t kLockboxSaltOffset = 0x5;
static const size_t kSectorSize = 512; static const size_t kSectorSize = 512;
static const size_t kExt4BlockSize = 4096; static const size_t kExt4BlockSize = 4096;
static const size_t kExt4MinBytes = 16 * 1024 * 1024; static const size_t kExt4MinBytes = 16 * 1024 * 1024;
static const char * const kStaticKeyDefault = "default unsafe static key";
static const char * const kStaticKeyFactory = "factory unsafe static key";
static const int kModeProduction = 0;
static const int kModeFactory = 1;
enum migration_method { enum migration_method {
MIGRATE_TEST_ONLY, MIGRATE_TEST_ONLY,
@@ -343,13 +347,25 @@ static int get_nvram_key(uint8_t *digest, int *old_lockbox)
* all the rest will fallback through various places (kernel command line, * all the rest will fallback through various places (kernel command line,
* BIOS UUID, and finally a static value) for a system key. * BIOS UUID, and finally a static value) for a system key.
*/ */
static int find_system_key(uint8_t *digest, int *migration_allowed) static int find_system_key(int mode, uint8_t *digest, int *migration_allowed)
{ {
gchar *key; gchar *key;
gsize length; gsize length;
/* By default, do not allow migration. */ /* By default, do not allow migration. */
*migration_allowed = 0; *migration_allowed = 0;
/* Factory mode uses a static system key. */
if (mode == kModeFactory) {
INFO("Using factory insecure system key.");
sha256((char *)kStaticKeyFactory, digest);
debug_dump_hex("system key", digest, DIGEST_LENGTH);
return 1;
}
/* Force ChromeOS devices into requiring the system key come from
* NVRAM.
*/
if (has_chromefw()) { if (has_chromefw()) {
int rc; int rc;
rc = get_nvram_key(digest, migration_allowed); rc = get_nvram_key(digest, migration_allowed);
@@ -379,7 +395,7 @@ static int find_system_key(uint8_t *digest, int *migration_allowed)
} }
INFO("Using default insecure system key."); INFO("Using default insecure system key.");
sha256("default unsafe static key", digest); sha256((char *)kStaticKeyDefault, digest);
debug_dump_hex("system key", digest, DIGEST_LENGTH); debug_dump_hex("system key", digest, DIGEST_LENGTH);
return 1; return 1;
} }
@@ -594,7 +610,10 @@ static int finalize_from_cmdline(char *key)
return EXIT_FAILURE; return EXIT_FAILURE;
} }
} else { } else {
if (!find_system_key(system_key, &migrate)) { /* Factory mode will never call finalize from the command
* line, so force Production mode here.
*/
if (!find_system_key(kModeProduction, system_key, &migrate)) {
ERROR("Could not locate system key."); ERROR("Could not locate system key.");
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@@ -650,7 +669,11 @@ out:
exit(0); exit(0);
} }
static int setup_encrypted(void) /* Do all the work needed to actually set up the encrypted partition.
* Takes "mode" argument to help determine where the system key should
* come from.
*/
static int setup_encrypted(int mode)
{ {
int has_system_key; int has_system_key;
uint8_t system_key[DIGEST_LENGTH]; uint8_t system_key[DIGEST_LENGTH];
@@ -666,7 +689,7 @@ static int setup_encrypted(void)
/* Use the "system key" to decrypt the "encryption key" stored in /* Use the "system key" to decrypt the "encryption key" stored in
* the stateful partition. * the stateful partition.
*/ */
has_system_key = find_system_key(system_key, &migrate_allowed); has_system_key = find_system_key(mode, system_key, &migrate_allowed);
if (has_system_key) { if (has_system_key) {
encryption_key = keyfile_read(key_path, system_key); encryption_key = keyfile_read(key_path, system_key);
} else { } else {
@@ -1129,6 +1152,7 @@ fail:
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
int okay; int okay;
int mode = kModeProduction;
INFO_INIT("Starting."); INFO_INIT("Starting.");
prepare_paths(); prepare_paths();
@@ -1137,24 +1161,28 @@ int main(int argc, char *argv[])
if (argc > 1) { if (argc > 1) {
if (!strcmp(argv[1], "umount")) if (!strcmp(argv[1], "umount"))
return shutdown(); return shutdown();
if (!strcmp(argv[1], "info")) else if (!strcmp(argv[1], "info"))
return report_info(); return report_info();
if (!strcmp(argv[1], "finalize")) else if (!strcmp(argv[1], "finalize"))
return finalize_from_cmdline(argc > 2 ? argv[2] : NULL); return finalize_from_cmdline(argc > 2 ? argv[2] : NULL);
else if (!strcmp(argv[1], "factory"))
fprintf(stderr, "Usage: %s [info|finalize|umount]\n", mode = kModeFactory;
argv[0]); else {
return 1; fprintf(stderr,
"Usage: %s [info|finalize|umount|factory]\n",
argv[0]);
return 1;
}
} }
check_mount_states(); check_mount_states();
okay = setup_encrypted(); okay = setup_encrypted(mode);
if (!okay) { if (!okay) {
INFO("Setup failed -- clearing files and retrying."); INFO("Setup failed -- clearing files and retrying.");
unlink(key_path); unlink(key_path);
unlink(block_path); unlink(block_path);
okay = setup_encrypted(); okay = setup_encrypted(mode);
} }
INFO_DONE("Done."); INFO_DONE("Done.");