Skip to content

Commit

Permalink
Fix compatibility for older dmcrypt without integrity_key_size
Browse files Browse the repository at this point in the history
For older kernel an default HMAC key size we must not set
integrity_key_size option.
  • Loading branch information
mbroz committed Dec 3, 2024
1 parent b567205 commit 5eda5f6
Show file tree
Hide file tree
Showing 4 changed files with 14 additions and 10 deletions.
2 changes: 1 addition & 1 deletion lib/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ int crypt_wipe_device(struct crypt_device *cd,

/* Internal integrity helpers */
const char *crypt_get_integrity(struct crypt_device *cd);
int crypt_get_integrity_key_size(struct crypt_device *cd);
int crypt_get_integrity_key_size(struct crypt_device *cd, bool dm_compat);
int crypt_get_integrity_tag_size(struct crypt_device *cd);

int crypt_key_in_keyring(struct crypt_device *cd);
Expand Down
2 changes: 1 addition & 1 deletion lib/luks2/luks2_json_metadata.c
Original file line number Diff line number Diff line change
Expand Up @@ -2737,7 +2737,7 @@ int LUKS2_activate(struct crypt_device *cd,
crypt_key, crypt_get_cipher_spec(cd),
crypt_get_iv_offset(cd), crypt_get_data_offset(cd),
crypt_get_integrity(cd) ?: "none",
crypt_get_integrity_key_size(cd), crypt_get_integrity_tag_size(cd),
crypt_get_integrity_key_size(cd, true), crypt_get_integrity_tag_size(cd),
crypt_get_sector_size(cd));
} else
r = dm_linear_target_set(&dmd.segment, 0,
Expand Down
18 changes: 11 additions & 7 deletions lib/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -1562,7 +1562,7 @@ static int _init_by_name_integrity(struct crypt_device *cd, const char *name)
if (tgt->u.integrity.journal_integrity_key)
cd->u.integrity.params.journal_integrity_key_size = tgt->u.integrity.journal_integrity_key->keylength;
if (tgt->u.integrity.journal_crypt_key)
cd->u.integrity.params.integrity_key_size = tgt->u.integrity.journal_crypt_key->keylength;
cd->u.integrity.params.journal_crypt_key_size = tgt->u.integrity.journal_crypt_key->keylength;
MOVE_REF(cd->metadata_device, tgt->u.integrity.meta_device);
}
out:
Expand Down Expand Up @@ -3756,7 +3756,7 @@ int crypt_resize(struct crypt_device *cd, const char *name, uint64_t new_size)
r = dm_crypt_target_set(&dmd.segment, 0, new_size, crypt_data_device(cd),
tgt->u.crypt.vk, crypt_get_cipher_spec(cd),
crypt_get_iv_offset(cd), crypt_get_data_offset(cd),
crypt_get_integrity(cd), crypt_get_integrity_key_size(cd), crypt_get_integrity_tag_size(cd),
crypt_get_integrity(cd), crypt_get_integrity_key_size(cd, true), crypt_get_integrity_tag_size(cd),
crypt_get_sector_size(cd));
if (r < 0)
goto out;
Expand Down Expand Up @@ -6215,13 +6215,17 @@ const char *crypt_get_integrity(struct crypt_device *cd)
}

/* INTERNAL only */
int crypt_get_integrity_key_size(struct crypt_device *cd)
int crypt_get_integrity_key_size(struct crypt_device *cd, bool dm_compat)
{
int key_size = 0;

if (isLUKS2(cd->type))
if (isLUKS2(cd->type)) {
key_size = INTEGRITY_key_size(crypt_get_integrity(cd),
LUKS2_get_integrity_key_size(&cd->u.luks2.hdr, CRYPT_DEFAULT_SEGMENT));
if (dm_compat && key_size > 0 &&
key_size == INTEGRITY_key_size(crypt_get_integrity(cd), 0))
return 0;
}

if (isINTEGRITY(cd->type) || !cd->type)
key_size = INTEGRITY_key_size(crypt_get_integrity(cd), 0);
Expand Down Expand Up @@ -6703,7 +6707,7 @@ int crypt_get_integrity_info(struct crypt_device *cd,
ip->buffer_sectors = cd->u.integrity.params.buffer_sectors;

ip->integrity = cd->u.integrity.params.integrity;
ip->integrity_key_size = crypt_get_integrity_key_size(cd);
ip->integrity_key_size = crypt_get_integrity_key_size(cd, false);

ip->journal_integrity = cd->u.integrity.params.journal_integrity;
ip->journal_integrity_key_size = cd->u.integrity.params.journal_integrity_key_size;
Expand All @@ -6722,7 +6726,7 @@ int crypt_get_integrity_info(struct crypt_device *cd,
ip->buffer_sectors = 0; // FIXME

ip->integrity = LUKS2_get_integrity(&cd->u.luks2.hdr, CRYPT_DEFAULT_SEGMENT);
ip->integrity_key_size = crypt_get_integrity_key_size(cd);
ip->integrity_key_size = crypt_get_integrity_key_size(cd, false);
ip->tag_size = INTEGRITY_tag_size(ip->integrity, crypt_get_cipher(cd), crypt_get_cipher_mode(cd));

ip->journal_integrity = NULL;
Expand All @@ -6736,7 +6740,7 @@ int crypt_get_integrity_info(struct crypt_device *cd,
} else if (!cd->type) {
memset(ip, 0, sizeof(*ip));
ip->integrity = crypt_get_integrity(cd);
ip->integrity_key_size = crypt_get_integrity_key_size(cd);
ip->integrity_key_size = crypt_get_integrity_key_size(cd, false);
ip->tag_size = crypt_get_integrity_tag_size(cd);
}

Expand Down
2 changes: 1 addition & 1 deletion lib/utils_dm.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ struct dm_target {
uint64_t iv_offset; /* IV initialisation sector */
uint32_t tag_size; /* additional on-disk tag size */
uint32_t sector_size; /* encryption sector size */
uint32_t integrity_key_size; /* for wrapped key HMAC */
uint32_t integrity_key_size; /* explicit integrity key size (HMAC), 0 for default */
} crypt;
struct {
struct device *hash_device;
Expand Down

0 comments on commit 5eda5f6

Please sign in to comment.