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;
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;
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,
.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
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);