From 95099d4622f8cb224d94e314c7a8e0df60b13f87 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Sat, 09 Dec 2023 08:38:01 +0000
Subject: [PATCH] enable docker ppp

---
 kernel/Documentation/block/inline-encryption.rst |  292 +++++++++++++++++++++++++++++++++++++---------------------
 1 files changed, 186 insertions(+), 106 deletions(-)

diff --git a/kernel/Documentation/block/inline-encryption.rst b/kernel/Documentation/block/inline-encryption.rst
index 330106b..7f9b40d 100644
--- a/kernel/Documentation/block/inline-encryption.rst
+++ b/kernel/Documentation/block/inline-encryption.rst
@@ -4,6 +4,22 @@
 Inline Encryption
 =================
 
+Background
+==========
+
+Inline encryption hardware sits logically between memory and the disk, and can
+en/decrypt data as it goes in/out of the disk. Inline encryption hardware has a
+fixed number of "keyslots" - slots into which encryption contexts (i.e. the
+encryption key, encryption algorithm, data unit size) can be programmed by the
+kernel at any time. Each request sent to the disk can be tagged with the index
+of a keyslot (and also a data unit number to act as an encryption tweak), and
+the inline encryption hardware will en/decrypt the data in the request with the
+encryption context programmed into that keyslot. This is very different from
+full disk encryption solutions like self encrypting drives/TCG OPAL/ATA
+Security standards, since with inline encryption, any block on disk could be
+encrypted with any encryption context the kernel chooses.
+
+
 Objective
 =========
 
@@ -18,27 +34,28 @@
 Constraints and notes
 =====================
 
-- IE hardware have a limited number of "keyslots" that can be programmed
+- IE hardware has a limited number of "keyslots" that can be programmed
   with an encryption context (key, algorithm, data unit size, etc.) at any time.
   One can specify a keyslot in a data request made to the device, and the
   device will en/decrypt the data using the encryption context programmed into
   that specified keyslot. When possible, we want to make multiple requests with
   the same encryption context share the same keyslot.
 
-- We need a way for filesystems to specify an encryption context to use for
-  en/decrypting a struct bio, and a device driver (like UFS) needs to be able
-  to use that encryption context when it processes the bio.
+- We need a way for upper layers like filesystems to specify an encryption
+  context to use for en/decrypting a struct bio, and a device driver (like UFS)
+  needs to be able to use that encryption context when it processes the bio.
 
-- We need a way for device drivers to expose their capabilities in a unified
-  way to the upper layers.
+- We need a way for device drivers to expose their inline encryption
+  capabilities in a unified way to the upper layers.
 
 
 Design
 ======
 
-We add a struct bio_crypt_ctx to struct bio that can represent an
-encryption context, because we need to be able to pass this encryption
-context from the FS layer to the device driver to act upon.
+We add a struct bio_crypt_ctx to struct bio that can
+represent an encryption context, because we need to be able to pass this
+encryption context from the upper layers (like the fs layer) to the
+device driver to act upon.
 
 While IE hardware works on the notion of keyslots, the FS layer has no
 knowledge of keyslots - it simply wants to specify an encryption context to
@@ -46,7 +63,7 @@
 
 We introduce a keyslot manager (KSM) that handles the translation from
 encryption contexts specified by the FS to keyslots on the IE hardware.
-This KSM also serves as the way IE hardware can expose their capabilities to
+This KSM also serves as the way IE hardware can expose its capabilities to
 upper layers. The generic mode of operation is: each device driver that wants
 to support IE will construct a KSM and set it up in its struct request_queue.
 Upper layers that want to use IE on this device can then use this KSM in
@@ -54,13 +71,7 @@
 a keyslot. The presence of the KSM in the request queue shall be used to mean
 that the device supports IE.
 
-On the device driver end of the interface, the device driver needs to tell the
-KSM how to actually manipulate the IE hardware in the device to do things like
-programming the crypto key into the IE hardware into a particular keyslot. All
-this is achieved through the :c:type:`struct keyslot_mgmt_ll_ops` that the
-device driver passes to the KSM when creating it.
-
-It uses refcounts to track which keyslots are idle (either they have no
+The KSM uses refcounts to track which keyslots are idle (either they have no
 encryption context programmed, or there are no in-flight struct bios
 referencing that keyslot). When a new encryption context needs a keyslot, it
 tries to find a keyslot that has already been programmed with the same
@@ -70,114 +81,183 @@
 is at least one.
 
 
-Blk-crypto
-==========
+blk-mq changes, other block layer changes and blk-crypto-fallback
+=================================================================
 
-The above is sufficient for simple cases, but does not work if there is a
-need for a crypto API fallback, or if we are want to use IE with layered
-devices. To these ends, we introduce blk-crypto. Blk-crypto allows us to
-present a unified view of encryption to the FS (so FS only needs to specify
-an encryption context and not worry about keyslots at all), and blk-crypto
-can decide whether to delegate the en/decryption to IE hardware or to the
-crypto API. Blk-crypto maintains an internal KSM that serves as the crypto
-API fallback.
+We add a pointer to a ``bi_crypt_context`` and ``keyslot`` to
+struct request. These will be referred to as the ``crypto fields``
+for the request. This ``keyslot`` is the keyslot into which the
+``bi_crypt_context`` has been programmed in the KSM of the ``request_queue``
+that this request is being sent to.
 
-Blk-crypto needs to ensure that the encryption context is programmed into the
-"correct" keyslot manager for IE. If a bio is submitted to a layered device
-that eventually passes the bio down to a device that really does support IE, we
-want the encryption context to be programmed into a keyslot for the KSM of the
-device with IE support. However, blk-crypto does not know a priori whether a
-particular device is the final device in the layering structure for a bio or
-not. So in the case that a particular device does not support IE, since it is
-possibly the final destination device for the bio, if the bio requires
-encryption (i.e. the bio is doing a write operation), blk-crypto must fallback
-to the crypto API *before* sending the bio to the device.
+We introduce ``block/blk-crypto-fallback.c``, which allows upper layers to remain
+blissfully unaware of whether or not real inline encryption hardware is present
+underneath. When a bio is submitted with a target ``request_queue`` that doesn't
+support the encryption context specified with the bio, the block layer will
+en/decrypt the bio with the blk-crypto-fallback.
 
-Blk-crypto ensures that:
+If the bio is a ``WRITE`` bio, a bounce bio is allocated, and the data in the bio
+is encrypted stored in the bounce bio - blk-mq will then proceed to process the
+bounce bio as if it were not encrypted at all (except when blk-integrity is
+concerned). ``blk-crypto-fallback`` sets the bounce bio's ``bi_end_io`` to an
+internal function that cleans up the bounce bio and ends the original bio.
 
-- The bio's encryption context is programmed into a keyslot in the KSM of the
-  request queue that the bio is being submitted to (or the crypto API fallback
-  KSM if the request queue doesn't have a KSM), and that the ``bc_ksm``
-  in the ``bi_crypt_context`` is set to this KSM
+If the bio is a ``READ`` bio, the bio's ``bi_end_io`` (and also ``bi_private``)
+is saved and overwritten by ``blk-crypto-fallback`` to
+``bio_crypto_fallback_decrypt_bio``.  The bio's ``bi_crypt_context`` is also
+overwritten with ``NULL``, so that to the rest of the stack, the bio looks
+as if it was a regular bio that never had an encryption context specified.
+``bio_crypto_fallback_decrypt_bio`` will decrypt the bio, restore the original
+``bi_end_io`` (and also ``bi_private``) and end the bio again.
 
-- That the bio has its own individual reference to the keyslot in this KSM.
-  Once the bio passes through blk-crypto, its encryption context is programmed
-  in some KSM. The "its own individual reference to the keyslot" ensures that
-  keyslots can be released by each bio independently of other bios while
-  ensuring that the bio has a valid reference to the keyslot when, for e.g., the
-  crypto API fallback KSM in blk-crypto performs crypto on the device's behalf.
-  The individual references are ensured by increasing the refcount for the
-  keyslot in the ``bc_ksm`` when a bio with a programmed encryption
-  context is cloned.
+Regardless of whether real inline encryption hardware is used or the
+blk-crypto-fallback is used, the ciphertext written to disk (and hence the
+on-disk format of data) will be the same (assuming the hardware's implementation
+of the algorithm being used adheres to spec and functions correctly).
+
+If a ``request queue``'s inline encryption hardware claimed to support the
+encryption context specified with a bio, then it will not be handled by the
+``blk-crypto-fallback``. We will eventually reach a point in blk-mq when a
+struct request needs to be allocated for that bio. At that point,
+blk-mq tries to program the encryption context into the ``request_queue``'s
+keyslot_manager, and obtain a keyslot, which it stores in its newly added
+``keyslot`` field. This keyslot is released when the request is completed.
+
+When the first bio is added to a request, ``blk_crypto_rq_bio_prep`` is called,
+which sets the request's ``crypt_ctx`` to a copy of the bio's
+``bi_crypt_context``. bio_crypt_do_front_merge is called whenever a subsequent
+bio is merged to the front of the request, which updates the ``crypt_ctx`` of
+the request so that it matches the newly merged bio's ``bi_crypt_context``. In particular, the request keeps a copy of the ``bi_crypt_context`` of the first
+bio in its bio-list (blk-mq needs to be careful to maintain this invariant
+during bio and request merges).
+
+To make it possible for inline encryption to work with request queue based
+layered devices, when a request is cloned, its ``crypto fields`` are cloned as
+well. When the cloned request is submitted, blk-mq programs the
+``bi_crypt_context`` of the request into the clone's request_queue's keyslot
+manager, and stores the returned keyslot in the clone's ``keyslot``.
 
 
-What blk-crypto does on bio submission
---------------------------------------
+API presented to users of the block layer
+=========================================
 
-**Case 1:** blk-crypto is given a bio with only an encryption context that hasn't
-been programmed into any keyslot in any KSM (for e.g. a bio from the FS).
-  In this case, blk-crypto will program the encryption context into the KSM of the
-  request queue the bio is being submitted to (and if this KSM does not exist,
-  then it will program it into blk-crypto's internal KSM for crypto API
-  fallback). The KSM that this encryption context was programmed into is stored
-  as the ``bc_ksm`` in the bio's ``bi_crypt_context``.
+``struct blk_crypto_key`` represents a crypto key (the raw key, size of the
+key, the crypto algorithm to use, the data unit size to use, and the number of
+bytes required to represent data unit numbers that will be specified with the
+``bi_crypt_context``).
 
-**Case 2:** blk-crypto is given a bio whose encryption context has already been
-programmed into a keyslot in the *crypto API fallback* KSM.
-  In this case, blk-crypto does nothing; it treats the bio as not having
-  specified an encryption context. Note that we cannot do here what we will do
-  in Case 3 because we would have already encrypted the bio via the crypto API
-  by this point.
+``blk_crypto_init_key`` allows upper layers to initialize such a
+``blk_crypto_key``.
 
-**Case 3:** blk-crypto is given a bio whose encryption context has already been
-programmed into a keyslot in some KSM (that is *not* the crypto API fallback
-KSM).
-  In this case, blk-crypto first releases that keyslot from that KSM and then
-  treats the bio as in Case 1.
+``bio_crypt_set_ctx`` should be called on any bio that a user of
+the block layer wants en/decrypted via inline encryption (or the
+blk-crypto-fallback, if hardware support isn't available for the desired
+crypto configuration). This function takes the ``blk_crypto_key`` and the
+data unit number (DUN) to use when en/decrypting the bio.
 
-This way, when a device driver is processing a bio, it can be sure that
-the bio's encryption context has been programmed into some KSM (either the
-device driver's request queue's KSM, or blk-crypto's crypto API fallback KSM).
-It then simply needs to check if the bio's ``bc_ksm`` is the device's
-request queue's KSM. If so, then it should proceed with IE. If not, it should
-simply do nothing with respect to crypto, because some other KSM (perhaps the
-blk-crypto crypto API fallback KSM) is handling the en/decryption.
+``blk_crypto_config_supported`` allows upper layers to query whether or not the
+an encryption context passed to request queue can be handled by blk-crypto
+(either by real inline encryption hardware, or by the blk-crypto-fallback).
+This is useful e.g. when blk-crypto-fallback is disabled, and the upper layer
+wants to use an algorithm that may not supported by hardware - this function
+lets the upper layer know ahead of time that the algorithm isn't supported,
+and the upper layer can fallback to something else if appropriate.
 
-Blk-crypto will release the keyslot that is being held by the bio (and also
-decrypt it if the bio is using the crypto API fallback KSM) once
-``bio_remaining_done`` returns true for the bio.
+``blk_crypto_start_using_key`` - Upper layers must call this function on
+``blk_crypto_key`` and a ``request_queue`` before using the key with any bio
+headed for that ``request_queue``. This function ensures that either the
+hardware supports the key's crypto settings, or the crypto API fallback has
+transforms for the needed mode allocated and ready to go. Note that this
+function may allocate an ``skcipher``, and must not be called from the data
+path, since allocating ``skciphers`` from the data path can deadlock.
 
+``blk_crypto_evict_key`` *must* be called by upper layers before a
+``blk_crypto_key`` is freed. Further, it *must* only be called only once
+there are no more in-flight requests that use that ``blk_crypto_key``.
+``blk_crypto_evict_key`` will ensure that a key is removed from any keyslots in
+inline encryption hardware that the key might have been programmed into (or the blk-crypto-fallback).
+
+API presented to device drivers
+===============================
+
+A :c:type:``struct blk_keyslot_manager`` should be set up by device drivers in
+the ``request_queue`` of the device. The device driver needs to call
+``blk_ksm_init`` (or its resource-managed variant ``devm_blk_ksm_init``) on the
+``blk_keyslot_manager``, while specifying the number of keyslots supported by
+the hardware.
+
+The device driver also needs to tell the KSM how to actually manipulate the
+IE hardware in the device to do things like programming the crypto key into
+the IE hardware into a particular keyslot. All this is achieved through the
+struct blk_ksm_ll_ops field in the KSM that the device driver
+must fill up after initing the ``blk_keyslot_manager``.
+
+The KSM also handles runtime power management for the device when applicable
+(e.g. when it wants to program a crypto key into the IE hardware, the device
+must be runtime powered on) - so the device driver must also set the ``dev``
+field in the ksm to point to the `struct device` for the KSM to use for runtime
+power management.
+
+``blk_ksm_reprogram_all_keys`` can be called by device drivers if the device
+needs each and every of its keyslots to be reprogrammed with the key it
+"should have" at the point in time when the function is called. This is useful
+e.g. if a device loses all its keys on runtime power down/up.
+
+If the driver used ``blk_ksm_init`` instead of ``devm_blk_ksm_init``, then
+``blk_ksm_destroy`` should be called to free up all resources used by a
+``blk_keyslot_manager`` once it is no longer needed.
 
 Layered Devices
 ===============
 
-Layered devices that wish to support IE need to create their own keyslot
-manager for their request queue, and expose whatever functionality they choose.
-When a layered device wants to pass a bio to another layer (either by
-resubmitting the same bio, or by submitting a clone), it doesn't need to do
-anything special because the bio (or the clone) will once again pass through
-blk-crypto, which will work as described in Case 3. If a layered device wants
-for some reason to do the IO by itself instead of passing it on to a child
-device, but it also chose to expose IE capabilities by setting up a KSM in its
-request queue, it is then responsible for en/decrypting the data itself. In
-such cases, the device can choose to call the blk-crypto function
-``blk_crypto_fallback_to_kernel_crypto_api`` (TODO: Not yet implemented), which will
-cause the en/decryption to be done via the crypto API fallback.
+Request queue based layered devices like dm-rq that wish to support IE need to
+create their own keyslot manager for their request queue, and expose whatever
+functionality they choose. When a layered device wants to pass a clone of that
+request to another ``request_queue``, blk-crypto will initialize and prepare the
+clone as necessary - see ``blk_crypto_insert_cloned_request`` in
+``blk-crypto.c``.
 
 
 Future Optimizations for layered devices
 ========================================
 
-Creating a keyslot manager for the layered device uses up memory for each
-keyslot, and in general, a layered device (like dm-linear) merely passes the
-request on to a "child" device, so the keyslots in the layered device itself
-might be completely unused. We can instead define a new type of KSM; the
-"passthrough KSM", that layered devices can use to let blk-crypto know that
-this layered device *will* pass the bio to some child device (and hence
-through blk-crypto again, at which point blk-crypto can program the encryption
-context, instead of programming it into the layered device's KSM). Again, if
-the device "lies" and decides to do the IO itself instead of passing it on to
-a child device, it is responsible for doing the en/decryption (and can choose
-to call ``blk_crypto_fallback_to_kernel_crypto_api``). Another use case for the
-"passthrough KSM" is for IE devices that want to manage their own keyslots/do
-not have a limited number of keyslots.
+Creating a keyslot manager for a layered device uses up memory for each
+keyslot, and in general, a layered device merely passes the request on to a
+"child" device, so the keyslots in the layered device itself are completely
+unused, and don't need any refcounting or keyslot programming. We can instead
+define a new type of KSM; the "passthrough KSM", that layered devices can use
+to advertise an unlimited number of keyslots, and support for any encryption
+algorithms they choose, while not actually using any memory for each keyslot.
+Another use case for the "passthrough KSM" is for IE devices that do not have a
+limited number of keyslots.
+
+
+Interaction between inline encryption and blk integrity
+=======================================================
+
+At the time of this patch, there is no real hardware that supports both these
+features. However, these features do interact with each other, and it's not
+completely trivial to make them both work together properly. In particular,
+when a WRITE bio wants to use inline encryption on a device that supports both
+features, the bio will have an encryption context specified, after which
+its integrity information is calculated (using the plaintext data, since
+the encryption will happen while data is being written), and the data and
+integrity info is sent to the device. Obviously, the integrity info must be
+verified before the data is encrypted. After the data is encrypted, the device
+must not store the integrity info that it received with the plaintext data
+since that might reveal information about the plaintext data. As such, it must
+re-generate the integrity info from the ciphertext data and store that on disk
+instead. Another issue with storing the integrity info of the plaintext data is
+that it changes the on disk format depending on whether hardware inline
+encryption support is present or the kernel crypto API fallback is used (since
+if the fallback is used, the device will receive the integrity info of the
+ciphertext, not that of the plaintext).
+
+Because there isn't any real hardware yet, it seems prudent to assume that
+hardware implementations might not implement both features together correctly,
+and disallow the combination for now. Whenever a device supports integrity, the
+kernel will pretend that the device does not support hardware inline encryption
+(by essentially setting the keyslot manager in the request_queue of the device
+to NULL). When the crypto API fallback is enabled, this means that all bios with
+and encryption context will use the fallback, and IO will complete as usual.
+When the fallback is disabled, a bio with an encryption context will be failed.

--
Gitblit v1.6.2