All of lore.kernel.org
 help / color / mirror / Atom feed
From: Eric Biggers <ebiggers@kernel.org>
To: Satya Tangirala <satyat@google.com>
Cc: linux-block@vger.kernel.org, linux-scsi@vger.kernel.org,
	linux-fscrypt@vger.kernel.org, linux-fsdevel@vger.kernel.org,
	linux-f2fs-devel@lists.sourceforge.net,
	linux-ext4@vger.kernel.org,
	Barani Muthukumaran <bmuthuku@qti.qualcomm.com>,
	Kuohong Wang <kuohong.wang@mediatek.com>,
	Kim Boojin <boojin.kim@samsung.com>
Subject: Re: [PATCH v12 03/12] block: Inline encryption support for blk-mq
Date: Wed, 13 May 2020 10:27:25 -0700	[thread overview]
Message-ID: <20200513172725.GC1243@sol.localdomain> (raw)
In-Reply-To: <20200430115959.238073-4-satyat@google.com>

On Thu, Apr 30, 2020 at 11:59:50AM +0000, Satya Tangirala wrote:
> We must have some way of letting a storage device driver know what
> encryption context it should use for en/decrypting a request. However,
> it's the upper layers (like the filesystem/fscrypt) that know about and
> manages encryption contexts. As such, when the upper layer submits a bio
> to the block layer, and this bio eventually reaches a device driver with
> support for inline encryption, the device driver will need to have been
> told the encryption context for that bio.
> 
> We want to communicate the encryption context from the upper layer to the
> storage device along with the bio, when the bio is submitted to the block
> layer. To do this, we add a struct bio_crypt_ctx to struct bio, which can
> represent an encryption context (note that we can't use the bi_private
> field in struct bio to do this because that field does not function to pass
> information across layers in the storage stack). We also introduce various
> functions to manipulate the bio_crypt_ctx and make the bio/request merging
> logic aware of the bio_crypt_ctx.
> 
> We also make changes to blk-mq to make it handle bios with encryption
> contexts. blk-mq can merge many bios into the same request. These bios need
> to have contiguous data unit numbers (the necessary changes to blk-merge
> are also made to ensure this) - as such, it suffices to keep the data unit
> number of just the first bio, since that's all a storage driver needs to
> infer the data unit number to use for each data block in each bio in a
> request. blk-mq keeps track of the encryption context to be used for all
> the bios in a request with the request's rq_crypt_ctx. When the first bio
> is added to an empty request, blk-mq will program the encryption context
> of that bio into the request_queue's keyslot manager, and store the
> returned keyslot in the request's rq_crypt_ctx. All the functions to
> operate on encryption contexts are in blk-crypto.c.
> 
> Upper layers only need to call bio_crypt_set_ctx with the encryption key,
> algorithm and data_unit_num; they don't have to worry about getting a
> keyslot for each encryption context, as blk-mq/blk-crypto handles that.
> Blk-crypto also makes it possible for request-based layered devices like
> dm-rq to make use of inline encryption hardware by cloning the
> rq_crypt_ctx and programming a keyslot in the new request_queue when
> necessary.
> 
> Note that any user of the block layer can submit bios with an
> encryption context, such as filesystems, device-mapper targets, etc.
> 
> Signed-off-by: Satya Tangirala <satyat@google.com>

Looks good, you can add:

    Reviewed-by: Eric Biggers <ebiggers@google.com>

A few comments for if you resend:

> @@ -647,6 +651,8 @@ bool bio_attempt_front_merge(struct request *req, struct bio *bio,
>  	req->__sector = bio->bi_iter.bi_sector;
>  	req->__data_len += bio->bi_iter.bi_size;
>  
> +	bio_crypt_attempt_front_merge(req, bio);
> +
>  	blk_account_io_start(req, false);
>  	return true;
>  }

I think this should be called "bio_crypt_do_front_merge()", since at this point
we've already decided to do the front merge, not just "attempt" it.
"bio_crypt_attempt_front_merge()" sounds like it should have a return value, so
it confused me at first glance.

> +/**
> + * blk_crypto_init_key() - Prepare a key for use with blk-crypto
> + * @blk_key: Pointer to the blk_crypto_key to initialize.
> + * @raw_key: Pointer to the raw key. Must be the correct length for the chosen
> + *	     @crypto_mode; see blk_crypto_modes[].
> + * @crypto_mode: identifier for the encryption algorithm to use
> + * @dun_bytes: number of bytes that will be used to specify the DUN when this
> + *	       key is used
> + * @data_unit_size: the data unit size to use for en/decryption
> + *
> + * Return: 0 on success, -errno on failure.  The caller is responsible for
> + *	   zeroizing both blk_key and raw_key when done with them.
> + */
> +int blk_crypto_init_key(struct blk_crypto_key *blk_key, const u8 *raw_key,
> +			enum blk_crypto_mode_num crypto_mode,
> +			unsigned int dun_bytes,
> +			unsigned int data_unit_size)
> +{
> +	const struct blk_crypto_mode *mode;
> +
> +	memset(blk_key, 0, sizeof(*blk_key));
> +
> +	if (crypto_mode >= ARRAY_SIZE(blk_crypto_modes))
> +		return -EINVAL;
> +
> +	mode = &blk_crypto_modes[crypto_mode];
> +	if (mode->keysize == 0)
> +		return -EINVAL;
> +
> +	if (!is_power_of_2(data_unit_size))
> +		return -EINVAL;

Since we're validating the crypto_mode and data_unit_size, we should validate
the dun_bytes too:

	if (dun_bytes <= 0 || dun_bytes > BLK_CRYPTO_MAX_IV_SIZE)
		return -EINVAL;

(One might argue that dun_bytes == 0 should be allowed in case we add support
for AES-ECB to blk-crypto, to align with the UFS specification which allows it.
But ECB isn't suitable for disk encryption and should never have been included
in the specification, so IMO we should reject dun_bytes==0 with prejudice :-) )

> @@ -2016,6 +2021,15 @@ static blk_qc_t blk_mq_make_request(struct request_queue *q, struct bio *bio)
>  
>  	blk_mq_bio_to_request(rq, bio, nr_segs);
>  
> +	ret = blk_crypto_init_request(rq);
> +	if (ret != BLK_STS_OK) {
> +		bio->bi_status = ret;
> +		bio_endio(bio);
> +		blk_mq_free_request(rq);
> +		return BLK_QC_T_NONE;
> +	}
> +
> +

There's an extra blank line here.

- Eric

WARNING: multiple messages have this Message-ID (diff)
From: Eric Biggers <ebiggers@kernel.org>
To: Satya Tangirala <satyat@google.com>
Cc: linux-scsi@vger.kernel.org, Kim Boojin <boojin.kim@samsung.com>,
	Kuohong Wang <kuohong.wang@mediatek.com>,
	Barani Muthukumaran <bmuthuku@qti.qualcomm.com>,
	linux-f2fs-devel@lists.sourceforge.net,
	linux-block@vger.kernel.org, linux-fscrypt@vger.kernel.org,
	linux-fsdevel@vger.kernel.org, linux-ext4@vger.kernel.org
Subject: Re: [f2fs-dev] [PATCH v12 03/12] block: Inline encryption support for blk-mq
Date: Wed, 13 May 2020 10:27:25 -0700	[thread overview]
Message-ID: <20200513172725.GC1243@sol.localdomain> (raw)
In-Reply-To: <20200430115959.238073-4-satyat@google.com>

On Thu, Apr 30, 2020 at 11:59:50AM +0000, Satya Tangirala wrote:
> We must have some way of letting a storage device driver know what
> encryption context it should use for en/decrypting a request. However,
> it's the upper layers (like the filesystem/fscrypt) that know about and
> manages encryption contexts. As such, when the upper layer submits a bio
> to the block layer, and this bio eventually reaches a device driver with
> support for inline encryption, the device driver will need to have been
> told the encryption context for that bio.
> 
> We want to communicate the encryption context from the upper layer to the
> storage device along with the bio, when the bio is submitted to the block
> layer. To do this, we add a struct bio_crypt_ctx to struct bio, which can
> represent an encryption context (note that we can't use the bi_private
> field in struct bio to do this because that field does not function to pass
> information across layers in the storage stack). We also introduce various
> functions to manipulate the bio_crypt_ctx and make the bio/request merging
> logic aware of the bio_crypt_ctx.
> 
> We also make changes to blk-mq to make it handle bios with encryption
> contexts. blk-mq can merge many bios into the same request. These bios need
> to have contiguous data unit numbers (the necessary changes to blk-merge
> are also made to ensure this) - as such, it suffices to keep the data unit
> number of just the first bio, since that's all a storage driver needs to
> infer the data unit number to use for each data block in each bio in a
> request. blk-mq keeps track of the encryption context to be used for all
> the bios in a request with the request's rq_crypt_ctx. When the first bio
> is added to an empty request, blk-mq will program the encryption context
> of that bio into the request_queue's keyslot manager, and store the
> returned keyslot in the request's rq_crypt_ctx. All the functions to
> operate on encryption contexts are in blk-crypto.c.
> 
> Upper layers only need to call bio_crypt_set_ctx with the encryption key,
> algorithm and data_unit_num; they don't have to worry about getting a
> keyslot for each encryption context, as blk-mq/blk-crypto handles that.
> Blk-crypto also makes it possible for request-based layered devices like
> dm-rq to make use of inline encryption hardware by cloning the
> rq_crypt_ctx and programming a keyslot in the new request_queue when
> necessary.
> 
> Note that any user of the block layer can submit bios with an
> encryption context, such as filesystems, device-mapper targets, etc.
> 
> Signed-off-by: Satya Tangirala <satyat@google.com>

Looks good, you can add:

    Reviewed-by: Eric Biggers <ebiggers@google.com>

A few comments for if you resend:

> @@ -647,6 +651,8 @@ bool bio_attempt_front_merge(struct request *req, struct bio *bio,
>  	req->__sector = bio->bi_iter.bi_sector;
>  	req->__data_len += bio->bi_iter.bi_size;
>  
> +	bio_crypt_attempt_front_merge(req, bio);
> +
>  	blk_account_io_start(req, false);
>  	return true;
>  }

I think this should be called "bio_crypt_do_front_merge()", since at this point
we've already decided to do the front merge, not just "attempt" it.
"bio_crypt_attempt_front_merge()" sounds like it should have a return value, so
it confused me at first glance.

> +/**
> + * blk_crypto_init_key() - Prepare a key for use with blk-crypto
> + * @blk_key: Pointer to the blk_crypto_key to initialize.
> + * @raw_key: Pointer to the raw key. Must be the correct length for the chosen
> + *	     @crypto_mode; see blk_crypto_modes[].
> + * @crypto_mode: identifier for the encryption algorithm to use
> + * @dun_bytes: number of bytes that will be used to specify the DUN when this
> + *	       key is used
> + * @data_unit_size: the data unit size to use for en/decryption
> + *
> + * Return: 0 on success, -errno on failure.  The caller is responsible for
> + *	   zeroizing both blk_key and raw_key when done with them.
> + */
> +int blk_crypto_init_key(struct blk_crypto_key *blk_key, const u8 *raw_key,
> +			enum blk_crypto_mode_num crypto_mode,
> +			unsigned int dun_bytes,
> +			unsigned int data_unit_size)
> +{
> +	const struct blk_crypto_mode *mode;
> +
> +	memset(blk_key, 0, sizeof(*blk_key));
> +
> +	if (crypto_mode >= ARRAY_SIZE(blk_crypto_modes))
> +		return -EINVAL;
> +
> +	mode = &blk_crypto_modes[crypto_mode];
> +	if (mode->keysize == 0)
> +		return -EINVAL;
> +
> +	if (!is_power_of_2(data_unit_size))
> +		return -EINVAL;

Since we're validating the crypto_mode and data_unit_size, we should validate
the dun_bytes too:

	if (dun_bytes <= 0 || dun_bytes > BLK_CRYPTO_MAX_IV_SIZE)
		return -EINVAL;

(One might argue that dun_bytes == 0 should be allowed in case we add support
for AES-ECB to blk-crypto, to align with the UFS specification which allows it.
But ECB isn't suitable for disk encryption and should never have been included
in the specification, so IMO we should reject dun_bytes==0 with prejudice :-) )

> @@ -2016,6 +2021,15 @@ static blk_qc_t blk_mq_make_request(struct request_queue *q, struct bio *bio)
>  
>  	blk_mq_bio_to_request(rq, bio, nr_segs);
>  
> +	ret = blk_crypto_init_request(rq);
> +	if (ret != BLK_STS_OK) {
> +		bio->bi_status = ret;
> +		bio_endio(bio);
> +		blk_mq_free_request(rq);
> +		return BLK_QC_T_NONE;
> +	}
> +
> +

There's an extra blank line here.

- Eric


_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

  parent reply	other threads:[~2020-05-13 17:27 UTC|newest]

Thread overview: 52+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-04-30 11:59 [PATCH v12 00/12] Inline Encryption Support Satya Tangirala
2020-04-30 11:59 ` [f2fs-dev] " Satya Tangirala via Linux-f2fs-devel
2020-04-30 11:59 ` [PATCH v12 01/12] Documentation: Document the blk-crypto framework Satya Tangirala
2020-04-30 11:59   ` [f2fs-dev] " Satya Tangirala via Linux-f2fs-devel
2020-05-13 16:47   ` Eric Biggers
2020-05-13 16:47     ` [f2fs-dev] " Eric Biggers
2020-04-30 11:59 ` [PATCH v12 02/12] block: Keyslot Manager for Inline Encryption Satya Tangirala
2020-04-30 11:59   ` [f2fs-dev] " Satya Tangirala via Linux-f2fs-devel
2020-05-13 13:35   ` Christoph Hellwig
2020-05-13 13:35     ` [f2fs-dev] " Christoph Hellwig
2020-05-13 16:59   ` Eric Biggers
2020-05-13 16:59     ` [f2fs-dev] " Eric Biggers
2020-04-30 11:59 ` [PATCH v12 03/12] block: Inline encryption support for blk-mq Satya Tangirala
2020-04-30 11:59   ` [f2fs-dev] " Satya Tangirala via Linux-f2fs-devel
2020-05-13 13:36   ` Christoph Hellwig
2020-05-13 13:36     ` [f2fs-dev] " Christoph Hellwig
2020-05-13 17:27   ` Eric Biggers [this message]
2020-05-13 17:27     ` Eric Biggers
2020-04-30 11:59 ` [PATCH v12 04/12] block: Make blk-integrity preclude hardware inline encryption Satya Tangirala
2020-04-30 11:59   ` [f2fs-dev] " Satya Tangirala via Linux-f2fs-devel
2020-05-13 13:37   ` Christoph Hellwig
2020-05-13 13:37     ` [f2fs-dev] " Christoph Hellwig
2020-05-13 17:30   ` Eric Biggers
2020-05-13 17:30     ` [f2fs-dev] " Eric Biggers
2020-04-30 11:59 ` [PATCH v12 05/12] block: blk-crypto-fallback for Inline Encryption Satya Tangirala
2020-04-30 11:59   ` [f2fs-dev] " Satya Tangirala via Linux-f2fs-devel
2020-05-13 18:05   ` Eric Biggers
2020-05-13 18:05     ` [f2fs-dev] " Eric Biggers
2020-04-30 11:59 ` [PATCH v12 06/12] scsi: ufs: UFS driver v2.1 spec crypto additions Satya Tangirala
2020-04-30 11:59   ` [f2fs-dev] " Satya Tangirala via Linux-f2fs-devel
2020-05-13 18:16   ` Eric Biggers
2020-05-13 18:16     ` [f2fs-dev] " Eric Biggers
2020-04-30 11:59 ` [PATCH v12 07/12] scsi: ufs: UFS crypto API Satya Tangirala
2020-04-30 11:59   ` [f2fs-dev] " Satya Tangirala via Linux-f2fs-devel
2020-05-13 18:16   ` Eric Biggers
2020-05-13 18:16     ` [f2fs-dev] " Eric Biggers
2020-04-30 11:59 ` [PATCH v12 08/12] scsi: ufs: Add inline encryption support to UFS Satya Tangirala
2020-04-30 11:59   ` [f2fs-dev] " Satya Tangirala via Linux-f2fs-devel
2020-05-13 18:19   ` Eric Biggers
2020-05-13 18:19     ` [f2fs-dev] " Eric Biggers
2020-04-30 11:59 ` [PATCH v12 09/12] fs: introduce SB_INLINECRYPT Satya Tangirala
2020-04-30 11:59   ` [f2fs-dev] " Satya Tangirala via Linux-f2fs-devel
2020-04-30 11:59 ` [PATCH v12 10/12] fscrypt: add inline encryption support Satya Tangirala
2020-04-30 11:59   ` [f2fs-dev] " Satya Tangirala via Linux-f2fs-devel
2020-04-30 17:04   ` Eric Biggers
2020-04-30 17:04     ` [f2fs-dev] " Eric Biggers
2020-04-30 11:59 ` [PATCH v12 11/12] f2fs: " Satya Tangirala
2020-04-30 11:59   ` [f2fs-dev] " Satya Tangirala via Linux-f2fs-devel
2020-04-30 11:59 ` [PATCH v12 12/12] ext4: " Satya Tangirala
2020-04-30 11:59   ` [f2fs-dev] " Satya Tangirala via Linux-f2fs-devel
2020-04-30 17:02 ` [PATCH v12 00/12] Inline Encryption Support Eric Biggers
2020-04-30 17:02   ` [f2fs-dev] " Eric Biggers

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=20200513172725.GC1243@sol.localdomain \
    --to=ebiggers@kernel.org \
    --cc=bmuthuku@qti.qualcomm.com \
    --cc=boojin.kim@samsung.com \
    --cc=kuohong.wang@mediatek.com \
    --cc=linux-block@vger.kernel.org \
    --cc=linux-ext4@vger.kernel.org \
    --cc=linux-f2fs-devel@lists.sourceforge.net \
    --cc=linux-fscrypt@vger.kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-scsi@vger.kernel.org \
    --cc=satyat@google.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.