diff --git a/src/partition/repart.c b/src/partition/repart.c index 829d80ddf0d..c87f42346db 100644 --- a/src/partition/repart.c +++ b/src/partition/repart.c @@ -207,7 +207,8 @@ typedef struct Partition { sd_id128_t current_uuid, new_uuid; bool new_uuid_is_set; char *current_label, *new_label; - sd_id128_t fs_uuid, luks_uuid; + sd_id128_t fs_uuid, luks_uuid, verity_uuid; + uint8_t verity_salt[SHA256_DIGEST_SIZE]; bool dropped; bool factory_reset; @@ -2188,6 +2189,12 @@ static int derive_uuid(sd_id128_t base, const char *token, sd_id128_t *ret) { return 0; } +static void derive_salt(sd_id128_t base, const char *token, uint8_t ret[static SHA256_DIGEST_SIZE]) { + assert(token); + + hmac_sha256(base.bytes, sizeof(base.bytes), token, strlen(token), ret); +} + static int context_load_partition_table(Context *context) { _cleanup_(fdisk_unref_contextp) struct fdisk_context *c = NULL; _cleanup_(fdisk_unref_tablep) struct fdisk_table *t = NULL; @@ -3900,7 +3907,7 @@ static int partition_format_verity_hash( cryptsetup_enable_logging(cd); r = sym_crypt_format( - cd, CRYPT_VERITY, NULL, NULL, NULL, NULL, 0, + cd, CRYPT_VERITY, NULL, NULL, SD_ID128_TO_UUID_STRING(p->verity_uuid), NULL, 0, &(struct crypt_params_verity){ .data_device = data_node, .flags = CRYPT_VERITY_CREATE_HASH, @@ -3908,7 +3915,8 @@ static int partition_format_verity_hash( .hash_type = 1, .data_block_size = context->sector_size, .hash_block_size = context->sector_size, - .salt_size = 32, + .salt_size = sizeof(p->verity_salt), + .salt = (const char*)p->verity_salt, }); if (r < 0) { /* libcryptsetup reports non-descriptive EIO errors for every I/O failure. Luckily, it @@ -4870,6 +4878,15 @@ static int context_acquire_partition_uuids_and_labels(Context *context) { return r; } + /* Derive the verity salt and verity superblock UUID from the seed to keep them reproducible */ + if (p->verity == VERITY_HASH) { + derive_salt(context->seed, "verity-salt", p->verity_salt); + + r = derive_uuid(context->seed, "verity-uuid", &p->verity_uuid); + if (r < 0) + return log_error_errno(r, "Failed to acquire verity uuid: %m"); + } + if (!isempty(p->current_label)) { /* never change initialized labels */ r = free_and_strdup_warn(&p->new_label, p->current_label);