diff --git a/meta-digi-dey/recipes-core/recovery/recovery-utils/recovery-utils/include/recovery.h b/meta-digi-dey/recipes-core/recovery/recovery-utils/recovery-utils/include/recovery.h index 0e29522b3..e73a86951 100644 --- a/meta-digi-dey/recipes-core/recovery/recovery-utils/recovery-utils/include/recovery.h +++ b/meta-digi-dey/recipes-core/recovery/recovery-utils/recovery-utils/include/recovery.h @@ -52,10 +52,11 @@ int wipe_update_partition(void); * * Params: * 'key' (input) Encryption key to use, NULL or empty to generate a random one + * 'force' (input) Skips warning and confirmation prompt if non-zero * - * Return: 0 on sucess, -1 on failure + * Return: 0 on sucess, -1 on failure and 1 on success with no recovery command set */ -int set_encryption_key(char *key); +int set_encryption_key(char *key, unsigned char force); /* * Configure recovery commands to encrypt/un-encrypt provided partitions. diff --git a/meta-digi-dey/recipes-core/recovery/recovery-utils/recovery-utils/lib/recovery.c b/meta-digi-dey/recipes-core/recovery/recovery-utils/recovery-utils/lib/recovery.c index ce1762341..b1c013b1a 100644 --- a/meta-digi-dey/recipes-core/recovery/recovery-utils/recovery-utils/lib/recovery.c +++ b/meta-digi-dey/recipes-core/recovery/recovery-utils/recovery-utils/lib/recovery.c @@ -70,6 +70,8 @@ static char *emmc_parts_blacklist[] = { NULL }; +static char *rootfs[] = { "rootfs", NULL }; + /* * Function: append_recovery_command * Description: append configuration to the 'recovery_command' variable @@ -640,11 +642,19 @@ int wipe_update_partition(void) * Function: set_encryption_key * Description: configure recovery commands to set a partition encryption key */ -int set_encryption_key(char *key) +int set_encryption_key(char *key, unsigned char force) { + char *parts[MAX_PARTITIONS]; + char *encrypted[MAX_PARTITIONS]; char *key_cmd = NULL; + char confirmation; int generate_random_key = 0; int ret = -1; + unsigned char i = 0; + + /* Initialize arrays */ + parts[0] = NULL; + encrypted[0] = NULL; generate_random_key = (!key || strlen(key) == 0); @@ -656,6 +666,46 @@ int set_encryption_key(char *key) print_open_device_warning(); + if (!force) { + /* Check if there are any currently encrypted partitions */ + ret = PARSE_PARTITION_INFO(parts, encrypted, MAX_PARTITIONS); + if (ret) { + fprintf(stderr, "Error: parse_partition_info\n"); + goto err; + } + + /* + * Key changes with an encrypted rootfs are only possible if + * an update package is provided, in which case, we're already + * substituting the current rootfs image with another one. + * Because of this, there's no need to print the warning if the + * rootfs is the only encrypted partition in the system. + */ + subtract_array(rootfs, encrypted); + + /* + * If we have at least one encrypted partition, ask for + * confirmation before continuing. + */ + if (encrypted[0]) { + printf("\n" + " *****************************************************************\n" + " * Warning: Changing the encryption key will erase the contents *\n" + " * of all currently encrypted partitions. *\n" + " *****************************************************************\n" + " Affected partitions:\n"); + while (encrypted[i]) + printf(" %s\n", encrypted[i++]); + printf("\n Continue? (y/n): "); + confirmation = getchar(); + if (confirmation != 'y' && confirmation != 'Y') { + printf("\nSkipping encryption key change\n"); + ret = 1; + goto err; + } + } + } + key_cmd = calloc(1, strlen("encryption_key=") + @@ -676,7 +726,10 @@ err: if (!generate_random_key) secure_memzero(key, strlen(key)); - return ret ? -1 : 0; + free_array(encrypted); + free_array(parts); + + return ret < 0 ? -1 : ret; } /* @@ -685,8 +738,6 @@ err: */ int encrypt_partitions(char *to_encrypt, char *to_unencrypt, unsigned char force) { - char *rootfs[] = { "rootfs", NULL }; - char *parts[MAX_PARTITIONS]; char *encrypted[MAX_PARTITIONS]; char *new_encrypted[MAX_PARTITIONS]; diff --git a/meta-digi-dey/recipes-core/recovery/recovery-utils/recovery-utils/recovery-reboot/recovery-reboot.c b/meta-digi-dey/recipes-core/recovery/recovery-utils/recovery-utils/recovery-reboot/recovery-reboot.c index 2ba2f80b6..142b2338a 100644 --- a/meta-digi-dey/recipes-core/recovery/recovery-utils/recovery-utils/recovery-reboot/recovery-reboot.c +++ b/meta-digi-dey/recipes-core/recovery/recovery-utils/recovery-utils/recovery-reboot/recovery-reboot.c @@ -48,7 +48,7 @@ " Empty to generate a random key.\n" \ " -w --wipe-update-partition Wipe 'update' partition\n" \ " -T --reboot-timeout= Reboot after N seconds (default %d)\n" \ - " -f --force Force (un)encryption operations.\n" \ + " -f --force Force (un)encryption and key change operations.\n" \ " --help Print help and exit\n" \ "\n" \ " Absolute path to the firmware update package\n" \ @@ -64,6 +64,7 @@ " -k [] --encryption-key[=] Set as file system encryption key.\n" \ " Empty to generate a random key.\n" \ " -T --reboot-timeout= Reboot after N seconds (default %d)\n" \ + " -f --force Force (un)encryption and key change operations.\n" \ " --help Print help and exit\n" \ "\n" \ " Absolute path to the firmware update package\n" \ @@ -81,7 +82,7 @@ " -k [] --encryption-key[=] Set as file system encryption key.\n" \ " Empty to generate a random key.\n" \ " -T --reboot-timeout= Reboot after N seconds (default %d)\n" \ - " -f --force Force (un)encryption operations.\n" \ + " -f --force Force (un)encryption and key change operations.\n" \ " --help Print help and exit\n" \ "\n" @@ -227,12 +228,20 @@ int main(int argc, char *argv[]) if (set_key) { /* Configure recovery commands to set a fs encryption key */ - ret = set_encryption_key(key); - if (ret) { + ret = set_encryption_key(key, force); + if (ret < 0) { printf("Error: set_encryption_key\n"); goto out; + } else if (ret == 0) { + /* + * Only reboot if strictly necessary, since the function + * might succeed without setting a recovery command + * (for example, if a user cancels the operation). + */ + need_reboot++; + } else { + ret = 0; } - need_reboot++; } if (swu_package) {