mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-05 16:00:05 +01:00
Switch crypt_activate_by_signed_key to keyslot context based activation.
It introduces new keyslot context type CRYPT_KC_TYPE_SIGNED_KEY.
This commit is contained in:
committed by
Daniel Zatovic
parent
e5bd99665e
commit
e43de57fac
@@ -251,91 +251,131 @@ int VERITY_UUID_generate(char **uuid_string)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int VERITY_verify_params(struct crypt_device *cd,
|
||||
struct crypt_params_verity *hdr,
|
||||
bool signed_root_hash,
|
||||
struct device *fec_device,
|
||||
struct volume_key *root_hash)
|
||||
{
|
||||
bool userspace_verification;
|
||||
int v, r;
|
||||
unsigned int fec_errors = 0;
|
||||
|
||||
assert(cd);
|
||||
assert(hdr);
|
||||
assert(root_hash);
|
||||
|
||||
log_dbg(cd, "Verifying VERITY device using hash %s.",
|
||||
hdr->hash_name);
|
||||
|
||||
userspace_verification = hdr->flags & CRYPT_VERITY_CHECK_HASH;
|
||||
|
||||
if (userspace_verification && signed_root_hash) {
|
||||
log_err(cd, _("Root hash signature verification is not supported."));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((hdr->flags & CRYPT_VERITY_ROOT_HASH_SIGNATURE) && !signed_root_hash) {
|
||||
log_err(cd, _("Root hash signature required."));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!userspace_verification)
|
||||
return 0;
|
||||
|
||||
log_dbg(cd, "Verification of VERITY data in userspace required.");
|
||||
r = VERITY_verify(cd, hdr, root_hash->key, root_hash->keylength);
|
||||
|
||||
if ((r == -EPERM || r == -EFAULT) && fec_device) {
|
||||
v = r;
|
||||
log_dbg(cd, "Verification failed, trying to repair with FEC device.");
|
||||
r = VERITY_FEC_process(cd, hdr, fec_device, 1, &fec_errors);
|
||||
if (r < 0)
|
||||
log_err(cd, _("Errors cannot be repaired with FEC device."));
|
||||
else if (fec_errors) {
|
||||
log_err(cd, _("Found %u repairable errors with FEC device."),
|
||||
fec_errors);
|
||||
/* If root hash failed, we cannot be sure it was properly repaired */
|
||||
}
|
||||
if (v == -EFAULT)
|
||||
r = -EPERM;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Activate verity device in kernel device-mapper */
|
||||
int VERITY_activate(struct crypt_device *cd,
|
||||
const char *name,
|
||||
const char *root_hash,
|
||||
size_t root_hash_size,
|
||||
const char *signature_description,
|
||||
struct volume_key *root_hash,
|
||||
struct volume_key *signature,
|
||||
struct device *fec_device,
|
||||
struct crypt_params_verity *verity_hdr,
|
||||
uint32_t activation_flags)
|
||||
{
|
||||
uint32_t dmv_flags;
|
||||
unsigned int fec_errors = 0;
|
||||
int r, v;
|
||||
struct crypt_dm_active_device dmd = {
|
||||
.size = verity_hdr->data_size * verity_hdr->data_block_size / 512,
|
||||
.flags = activation_flags,
|
||||
.uuid = crypt_get_uuid(cd),
|
||||
};
|
||||
int r;
|
||||
char *description = NULL;
|
||||
struct crypt_dm_active_device dmd = { 0 };
|
||||
|
||||
log_dbg(cd, "Trying to activate VERITY device %s using hash %s.",
|
||||
name ?: "[none]", verity_hdr->hash_name);
|
||||
assert(name);
|
||||
assert(root_hash);
|
||||
assert(verity_hdr);
|
||||
|
||||
if (verity_hdr->flags & CRYPT_VERITY_CHECK_HASH) {
|
||||
if (signature_description) {
|
||||
log_err(cd, _("Root hash signature verification is not supported."));
|
||||
return -EINVAL;
|
||||
}
|
||||
dmd.size = verity_hdr->data_size * verity_hdr->data_block_size / 512;
|
||||
dmd.flags = activation_flags;
|
||||
dmd.uuid = crypt_get_uuid(cd);
|
||||
|
||||
log_dbg(cd, "Verification of data in userspace required.");
|
||||
r = VERITY_verify(cd, verity_hdr, root_hash, root_hash_size);
|
||||
|
||||
if ((r == -EPERM || r == -EFAULT) && fec_device) {
|
||||
v = r;
|
||||
log_dbg(cd, "Verification failed, trying to repair with FEC device.");
|
||||
r = VERITY_FEC_process(cd, verity_hdr, fec_device, 1, &fec_errors);
|
||||
if (r < 0)
|
||||
log_err(cd, _("Errors cannot be repaired with FEC device."));
|
||||
else if (fec_errors) {
|
||||
log_err(cd, _("Found %u repairable errors with FEC device."),
|
||||
fec_errors);
|
||||
/* If root hash failed, we cannot be sure it was properly repaired */
|
||||
}
|
||||
if (v == -EFAULT)
|
||||
r = -EPERM;
|
||||
}
|
||||
log_dbg(cd, "Activating VERITY device %s using hash %s.",
|
||||
name, verity_hdr->hash_name);
|
||||
|
||||
if (signature) {
|
||||
r = asprintf(&description, "cryptsetup:%s%s%s",
|
||||
crypt_get_uuid(cd) ?: "", crypt_get_uuid(cd) ? "-" : "", name);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
return -EINVAL;
|
||||
|
||||
if (!name)
|
||||
return 0;
|
||||
log_dbg(cd, "Adding signature into keyring %s", description);
|
||||
r = keyring_add_key_in_thread_keyring(USER_KEY, description, signature->key, signature->keylength);
|
||||
if (r) {
|
||||
log_err(cd, _("Failed to load key in kernel keyring."));
|
||||
free(description);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
r = device_block_adjust(cd, crypt_metadata_device(cd), DEV_OK,
|
||||
0, NULL, NULL);
|
||||
if (r)
|
||||
return r;
|
||||
goto out;
|
||||
|
||||
r = device_block_adjust(cd, crypt_data_device(cd), DEV_EXCL,
|
||||
0, &dmd.size, &dmd.flags);
|
||||
if (r)
|
||||
return r;
|
||||
goto out;
|
||||
|
||||
if (fec_device) {
|
||||
r = device_block_adjust(cd, fec_device, DEV_OK,
|
||||
0, NULL, NULL);
|
||||
if (r)
|
||||
return r;
|
||||
goto out;
|
||||
}
|
||||
|
||||
r = dm_verity_target_set(&dmd.segment, 0, dmd.size, crypt_data_device(cd),
|
||||
crypt_metadata_device(cd), fec_device, root_hash,
|
||||
root_hash_size, signature_description,
|
||||
crypt_metadata_device(cd), fec_device, root_hash->key,
|
||||
root_hash->keylength, description,
|
||||
VERITY_hash_offset_block(verity_hdr),
|
||||
VERITY_FEC_blocks(cd, fec_device, verity_hdr), verity_hdr);
|
||||
|
||||
if (r)
|
||||
return r;
|
||||
goto out;
|
||||
|
||||
r = dm_create_device(cd, name, CRYPT_VERITY, &dmd);
|
||||
if (r < 0 && (dm_flags(cd, DM_VERITY, &dmv_flags) || !(dmv_flags & DM_VERITY_SUPPORTED))) {
|
||||
log_err(cd, _("Kernel does not support dm-verity mapping."));
|
||||
r = -ENOTSUP;
|
||||
}
|
||||
if (r < 0 && signature_description && !(dmv_flags & DM_VERITY_SIGNATURE_SUPPORTED)) {
|
||||
if (r < 0 && signature && !(dmv_flags & DM_VERITY_SIGNATURE_SUPPORTED)) {
|
||||
log_err(cd, _("Kernel does not support dm-verity signature option."));
|
||||
r = -ENOTSUP;
|
||||
}
|
||||
@@ -351,6 +391,8 @@ int VERITY_activate(struct crypt_device *cd,
|
||||
|
||||
r = 0;
|
||||
out:
|
||||
crypt_drop_keyring_key_by_description(cd, description, USER_KEY);
|
||||
free(description);
|
||||
dm_targets_free(cd, &dmd);
|
||||
return r;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user