public inbox for linux-block@vger.kernel.org
 help / color / mirror / Atom feed
From: Eric Biggers <ebiggers@kernel.org>
To: Israel Rukshin <israelr@nvidia.com>
Cc: Linux-block <linux-block@vger.kernel.org>,
	Jens Axboe <axboe@kernel.dk>, Christoph Hellwig <hch@lst.de>,
	Nitzan Carmi <nitzanc@nvidia.com>,
	Max Gurtovoy <mgurtovoy@nvidia.com>
Subject: Re: [PATCH 1/1] block: Add support for setting inline encryption key per block device
Date: Mon, 25 Jul 2022 17:42:50 -0700	[thread overview]
Message-ID: <Yt84ihS95qsGWv1K@sol.localdomain> (raw)
In-Reply-To: <1658316391-13472-2-git-send-email-israelr@nvidia.com>

On Wed, Jul 20, 2022 at 02:26:31PM +0300, Israel Rukshin wrote:
> +static int blk_crypto_ioctl_create_key(struct request_queue *q,
> +				       void __user *argp)
> +{
> +	struct blk_crypto_set_key_arg arg;
> +	u8 raw_key[BLK_CRYPTO_MAX_KEY_SIZE];
> +	struct blk_crypto_key *blk_key;
> +	int ret;
> +
> +	if (copy_from_user(&arg, argp, sizeof(arg)))
> +		return -EFAULT;
> +
> +	if (memchr_inv(arg.reserved, 0, sizeof(arg.reserved)))
> +		return -EINVAL;
> +
> +	if (!arg.raw_key_size)
> +		return blk_crypto_destroy_default_key(q);
> +
> +	if (q->blk_key) {
> +		pr_err("Crypto key is already configured\n");
> +		return -EBUSY;
> +	}

Doesn't this need locking so that multiple executions of this ioctl can't run on
the block device at the same time?

Also, the key is actually being associated with the request_queue.  I thought it
was going to be the block_device?  Doesn't it have to be the block_device so
that different partitions on the same disk can have different settings?

Also, the pr_err should be removed.  Likewise in several places below.

> +
> +	if (arg.raw_key_size > sizeof(raw_key))
> +		return -EINVAL;
> +
> +	if (arg.data_unit_size > queue_logical_block_size(q)) {
> +		pr_err("Data unit size is bigger than logical block size\n");
> +		return -EINVAL;
> +	}
> +
> +	if (copy_from_user(raw_key, u64_to_user_ptr(arg.raw_key_ptr),
> +			   arg.raw_key_size)) {
> +		ret = -EFAULT;
> +		goto err;
> +	}
> +
> +	blk_key = kzalloc(sizeof(*blk_key), GFP_KERNEL);
> +	if (!blk_key) {
> +		ret = -ENOMEM;
> +		goto err;
> +	}
> +
> +	ret = blk_crypto_init_key(blk_key, raw_key, arg.crypto_mode,
> +				  sizeof(u64), arg.data_unit_size);
> +	if (ret) {
> +		pr_err("Failed to init inline encryption key\n");
> +		goto key_err;
> +	}
> +
> +	/* Block key size is taken from crypto mode */
> +	if (arg.raw_key_size != blk_key->size) {
> +		ret = -EINVAL;
> +		goto key_err;
> +	}

The key size check above happens too late.  The easiest solution would be to add
the key size as an argument to blk_crypto_init_key(), and make it validate the
key size.

> +	}
> +	blk_key->q = q;
> +	q->blk_key = blk_key;

How does this interact with concurrent I/O?  Also, doesn't the block device's
page cache need to be invalidated when a key is set or removed?

> diff --git a/include/uapi/linux/blk-crypto.h b/include/uapi/linux/blk-crypto.h
> new file mode 100644
> index 000000000000..5a65ebaf6038
> --- /dev/null
> +++ b/include/uapi/linux/blk-crypto.h
> @@ -0,0 +1,14 @@
> +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
> +
> +#ifndef __UAPI_LINUX_BLK_CRYPTO_H
> +#define __UAPI_LINUX_BLK_CRYPTO_H
> +
> +enum blk_crypto_mode_num {
> +	BLK_ENCRYPTION_MODE_INVALID,
> +	BLK_ENCRYPTION_MODE_AES_256_XTS,
> +	BLK_ENCRYPTION_MODE_AES_128_CBC_ESSIV,
> +	BLK_ENCRYPTION_MODE_ADIANTUM,
> +	BLK_ENCRYPTION_MODE_MAX,
> +};

Instead of an enum, these should use #define's with explicit numbers.  Also,
INVALID and MAX shouldn't be included.

> +
> +#endif /* __UAPI_LINUX_BLK_CRYPTO_H */
> diff --git a/include/uapi/linux/fs.h b/include/uapi/linux/fs.h
> index bdf7b404b3e7..398a77895e96 100644
> --- a/include/uapi/linux/fs.h
> +++ b/include/uapi/linux/fs.h
> @@ -121,6 +121,14 @@ struct fsxattr {
>  	unsigned char	fsx_pad[8];
>  };
>  
> +struct blk_crypto_set_key_arg {
> +	__u32 crypto_mode;
> +	__u64 raw_key_ptr;
> +	__u32 raw_key_size;
> +	__u32 data_unit_size;
> +	__u32 reserved[9];	/* must be zero */
> +};

The reserved fields should be __u64 so that it's easy to use them for pointers
or other 64-bit data later if it becomes necessary.  Also, reserved fields
should also be prefixed with "__".  Also, a padding field is needed between
crypto_mode and raw_key_ptr.  Also, it would be a good idea to make the reserved
space even larger, as people may want to add all sorts of weird settings here in
the future (look at dm-crypt).

The following might be good; it makes the whole struct a nice round size, 128
bytes:

struct blk_crypto_set_key_arg {
	__u32 crypto_mode;
	__u32 __reserved1;
	__u64 raw_key_ptr;
	__u32 raw_key_size;
	__u32 data_unit_size;
	__u64 __reserved2[13];
};

- Eric

  parent reply	other threads:[~2022-07-26  0:42 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-07-20 11:26 [PATCH 0/1 RFC] block: Add ioctl for setting default inline crypto key Israel Rukshin
2022-07-20 11:26 ` [PATCH 1/1] block: Add support for setting inline encryption key per block device Israel Rukshin
2022-07-21  6:49   ` Eric Biggers
2022-07-21 12:54     ` Christoph Hellwig
2022-07-22  8:20       ` [dm-devel] " Milan Broz
2022-07-26  2:40     ` Daniil Lunev
2022-07-21 12:51   ` Christoph Hellwig
2022-07-26  0:42   ` Eric Biggers [this message]
2022-07-28 16:26     ` Israel Rukshin
2022-07-21 12:44 ` [PATCH 0/1 RFC] block: Add ioctl for setting default inline crypto key Christoph Hellwig

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=Yt84ihS95qsGWv1K@sol.localdomain \
    --to=ebiggers@kernel.org \
    --cc=axboe@kernel.dk \
    --cc=hch@lst.de \
    --cc=israelr@nvidia.com \
    --cc=linux-block@vger.kernel.org \
    --cc=mgurtovoy@nvidia.com \
    --cc=nitzanc@nvidia.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox