Commit 4441686b authored by Ingo Franzki's avatar Ingo Franzki Committed by Mikulas Patocka
Browse files

dm-crypt: Allow to specify the integrity key size as option



For the MAC based integrity operation, the integrity key size (i.e.
key_mac_size) is currently set to the digest size of the used digest.

For wrapped key HMAC algorithms, the key size is independent of the
cryptographic key size. So there is no known size of the mac key in
such cases. The desired key size can optionally be specified as argument
when the dm-crypt device is configured via 'integrity_key_size:%u'.
If no integrity_key_size argument is specified, the mac key size
is still set to the digest size, as before.

Increase version number to 1.28.0 so that support for the new
argument can be detected by user space (i.e. cryptsetup).

Signed-off-by: default avatarIngo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: default avatarMilan Broz <gmazyland@gmail.com>
Signed-off-by: default avatarMikulas Patocka <mpatocka@redhat.com>
parent f3631ae1
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -160,6 +160,10 @@ iv_large_sectors
   The <iv_offset> must be multiple of <sector_size> (in 512 bytes units)
   if this flag is specified.

integrity_key_size:<bytes>
   Use an integrity key of <bytes> size instead of using an integrity key size
   of the digest size of the used HMAC algorithm.


Module parameters::

+15 −4
Original line number Diff line number Diff line
@@ -147,6 +147,7 @@ enum cipher_flags {
	CRYPT_MODE_INTEGRITY_AEAD,	/* Use authenticated mode for cipher */
	CRYPT_IV_LARGE_SECTORS,		/* Calculate IV from sector_size, not 512B sectors */
	CRYPT_ENCRYPT_PREPROCESS,	/* Must preprocess data for encryption (elephant) */
	CRYPT_KEY_MAC_SIZE_SET,		/* The integrity_key_size option was used */
};

/*
@@ -2937,6 +2938,7 @@ static int crypt_ctr_auth_cipher(struct crypt_config *cc, char *cipher_api)
	if (IS_ERR(mac))
		return PTR_ERR(mac);

	if (!test_bit(CRYPT_KEY_MAC_SIZE_SET, &cc->cipher_flags))
		cc->key_mac_size = crypto_ahash_digestsize(mac);
	crypto_free_ahash(mac);

@@ -3219,6 +3221,13 @@ static int crypt_ctr_optional(struct dm_target *ti, unsigned int argc, char **ar
			cc->cipher_auth = kstrdup(sval, GFP_KERNEL);
			if (!cc->cipher_auth)
				return -ENOMEM;
		} else if (sscanf(opt_string, "integrity_key_size:%u%c", &val, &dummy) == 1) {
			if (!val) {
				ti->error = "Invalid integrity_key_size argument";
				return -EINVAL;
			}
			cc->key_mac_size = val;
			set_bit(CRYPT_KEY_MAC_SIZE_SET, &cc->cipher_flags);
		} else if (sscanf(opt_string, "sector_size:%hu%c", &cc->sector_size, &dummy) == 1) {
			if (cc->sector_size < (1 << SECTOR_SHIFT) ||
			    cc->sector_size > 4096 ||
@@ -3607,10 +3616,10 @@ static void crypt_status(struct dm_target *ti, status_type_t type,
		num_feature_args += test_bit(DM_CRYPT_NO_OFFLOAD, &cc->flags);
		num_feature_args += test_bit(DM_CRYPT_NO_READ_WORKQUEUE, &cc->flags);
		num_feature_args += test_bit(DM_CRYPT_NO_WRITE_WORKQUEUE, &cc->flags);
		num_feature_args += !!cc->used_tag_size;
		num_feature_args += cc->sector_size != (1 << SECTOR_SHIFT);
		num_feature_args += test_bit(CRYPT_IV_LARGE_SECTORS, &cc->cipher_flags);
		if (cc->used_tag_size)
			num_feature_args++;
		num_feature_args += test_bit(CRYPT_KEY_MAC_SIZE_SET, &cc->cipher_flags);
		if (num_feature_args) {
			DMEMIT(" %d", num_feature_args);
			if (ti->num_discard_bios)
@@ -3631,6 +3640,8 @@ static void crypt_status(struct dm_target *ti, status_type_t type,
				DMEMIT(" sector_size:%d", cc->sector_size);
			if (test_bit(CRYPT_IV_LARGE_SECTORS, &cc->cipher_flags))
				DMEMIT(" iv_large_sectors");
			if (test_bit(CRYPT_KEY_MAC_SIZE_SET, &cc->cipher_flags))
				DMEMIT(" integrity_key_size:%u", cc->key_mac_size);
		}
		break;

@@ -3758,7 +3769,7 @@ static void crypt_io_hints(struct dm_target *ti, struct queue_limits *limits)

static struct target_type crypt_target = {
	.name   = "crypt",
	.version = {1, 27, 0},
	.version = {1, 28, 0},
	.module = THIS_MODULE,
	.ctr    = crypt_ctr,
	.dtr    = crypt_dtr,