mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-11-24 02:05:01 +00:00
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:
@@ -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.");
|
||||||
|
|||||||
Reference in New Issue
Block a user