18c2ecf20Sopenharmony_ci.. SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci
38c2ecf20Sopenharmony_ci=================
48c2ecf20Sopenharmony_ciInline Encryption
58c2ecf20Sopenharmony_ci=================
68c2ecf20Sopenharmony_ci
78c2ecf20Sopenharmony_ciBackground
88c2ecf20Sopenharmony_ci==========
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ciInline encryption hardware sits logically between memory and the disk, and can
118c2ecf20Sopenharmony_cien/decrypt data as it goes in/out of the disk. Inline encryption hardware has a
128c2ecf20Sopenharmony_cifixed number of "keyslots" - slots into which encryption contexts (i.e. the
138c2ecf20Sopenharmony_ciencryption key, encryption algorithm, data unit size) can be programmed by the
148c2ecf20Sopenharmony_cikernel at any time. Each request sent to the disk can be tagged with the index
158c2ecf20Sopenharmony_ciof a keyslot (and also a data unit number to act as an encryption tweak), and
168c2ecf20Sopenharmony_cithe inline encryption hardware will en/decrypt the data in the request with the
178c2ecf20Sopenharmony_ciencryption context programmed into that keyslot. This is very different from
188c2ecf20Sopenharmony_cifull disk encryption solutions like self encrypting drives/TCG OPAL/ATA
198c2ecf20Sopenharmony_ciSecurity standards, since with inline encryption, any block on disk could be
208c2ecf20Sopenharmony_ciencrypted with any encryption context the kernel chooses.
218c2ecf20Sopenharmony_ci
228c2ecf20Sopenharmony_ci
238c2ecf20Sopenharmony_ciObjective
248c2ecf20Sopenharmony_ci=========
258c2ecf20Sopenharmony_ci
268c2ecf20Sopenharmony_ciWe want to support inline encryption (IE) in the kernel.
278c2ecf20Sopenharmony_ciTo allow for testing, we also want a crypto API fallback when actual
288c2ecf20Sopenharmony_ciIE hardware is absent. We also want IE to work with layered devices
298c2ecf20Sopenharmony_cilike dm and loopback (i.e. we want to be able to use the IE hardware
308c2ecf20Sopenharmony_ciof the underlying devices if present, or else fall back to crypto API
318c2ecf20Sopenharmony_cien/decryption).
328c2ecf20Sopenharmony_ci
338c2ecf20Sopenharmony_ci
348c2ecf20Sopenharmony_ciConstraints and notes
358c2ecf20Sopenharmony_ci=====================
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_ci- IE hardware has a limited number of "keyslots" that can be programmed
388c2ecf20Sopenharmony_ci  with an encryption context (key, algorithm, data unit size, etc.) at any time.
398c2ecf20Sopenharmony_ci  One can specify a keyslot in a data request made to the device, and the
408c2ecf20Sopenharmony_ci  device will en/decrypt the data using the encryption context programmed into
418c2ecf20Sopenharmony_ci  that specified keyslot. When possible, we want to make multiple requests with
428c2ecf20Sopenharmony_ci  the same encryption context share the same keyslot.
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_ci- We need a way for upper layers like filesystems to specify an encryption
458c2ecf20Sopenharmony_ci  context to use for en/decrypting a struct bio, and a device driver (like UFS)
468c2ecf20Sopenharmony_ci  needs to be able to use that encryption context when it processes the bio.
478c2ecf20Sopenharmony_ci
488c2ecf20Sopenharmony_ci- We need a way for device drivers to expose their inline encryption
498c2ecf20Sopenharmony_ci  capabilities in a unified way to the upper layers.
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_ciDesign
538c2ecf20Sopenharmony_ci======
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_ciWe add a struct bio_crypt_ctx to struct bio that can
568c2ecf20Sopenharmony_cirepresent an encryption context, because we need to be able to pass this
578c2ecf20Sopenharmony_ciencryption context from the upper layers (like the fs layer) to the
588c2ecf20Sopenharmony_cidevice driver to act upon.
598c2ecf20Sopenharmony_ci
608c2ecf20Sopenharmony_ciWhile IE hardware works on the notion of keyslots, the FS layer has no
618c2ecf20Sopenharmony_ciknowledge of keyslots - it simply wants to specify an encryption context to
628c2ecf20Sopenharmony_ciuse while en/decrypting a bio.
638c2ecf20Sopenharmony_ci
648c2ecf20Sopenharmony_ciWe introduce a keyslot manager (KSM) that handles the translation from
658c2ecf20Sopenharmony_ciencryption contexts specified by the FS to keyslots on the IE hardware.
668c2ecf20Sopenharmony_ciThis KSM also serves as the way IE hardware can expose its capabilities to
678c2ecf20Sopenharmony_ciupper layers. The generic mode of operation is: each device driver that wants
688c2ecf20Sopenharmony_cito support IE will construct a KSM and set it up in its struct request_queue.
698c2ecf20Sopenharmony_ciUpper layers that want to use IE on this device can then use this KSM in
708c2ecf20Sopenharmony_cithe device's struct request_queue to translate an encryption context into
718c2ecf20Sopenharmony_cia keyslot. The presence of the KSM in the request queue shall be used to mean
728c2ecf20Sopenharmony_cithat the device supports IE.
738c2ecf20Sopenharmony_ci
748c2ecf20Sopenharmony_ciThe KSM uses refcounts to track which keyslots are idle (either they have no
758c2ecf20Sopenharmony_ciencryption context programmed, or there are no in-flight struct bios
768c2ecf20Sopenharmony_cireferencing that keyslot). When a new encryption context needs a keyslot, it
778c2ecf20Sopenharmony_citries to find a keyslot that has already been programmed with the same
788c2ecf20Sopenharmony_ciencryption context, and if there is no such keyslot, it evicts the least
798c2ecf20Sopenharmony_cirecently used idle keyslot and programs the new encryption context into that
808c2ecf20Sopenharmony_cione. If no idle keyslots are available, then the caller will sleep until there
818c2ecf20Sopenharmony_ciis at least one.
828c2ecf20Sopenharmony_ci
838c2ecf20Sopenharmony_ci
848c2ecf20Sopenharmony_ciblk-mq changes, other block layer changes and blk-crypto-fallback
858c2ecf20Sopenharmony_ci=================================================================
868c2ecf20Sopenharmony_ci
878c2ecf20Sopenharmony_ciWe add a pointer to a ``bi_crypt_context`` and ``keyslot`` to
888c2ecf20Sopenharmony_cistruct request. These will be referred to as the ``crypto fields``
898c2ecf20Sopenharmony_cifor the request. This ``keyslot`` is the keyslot into which the
908c2ecf20Sopenharmony_ci``bi_crypt_context`` has been programmed in the KSM of the ``request_queue``
918c2ecf20Sopenharmony_cithat this request is being sent to.
928c2ecf20Sopenharmony_ci
938c2ecf20Sopenharmony_ciWe introduce ``block/blk-crypto-fallback.c``, which allows upper layers to remain
948c2ecf20Sopenharmony_ciblissfully unaware of whether or not real inline encryption hardware is present
958c2ecf20Sopenharmony_ciunderneath. When a bio is submitted with a target ``request_queue`` that doesn't
968c2ecf20Sopenharmony_cisupport the encryption context specified with the bio, the block layer will
978c2ecf20Sopenharmony_cien/decrypt the bio with the blk-crypto-fallback.
988c2ecf20Sopenharmony_ci
998c2ecf20Sopenharmony_ciIf the bio is a ``WRITE`` bio, a bounce bio is allocated, and the data in the bio
1008c2ecf20Sopenharmony_ciis encrypted stored in the bounce bio - blk-mq will then proceed to process the
1018c2ecf20Sopenharmony_cibounce bio as if it were not encrypted at all (except when blk-integrity is
1028c2ecf20Sopenharmony_ciconcerned). ``blk-crypto-fallback`` sets the bounce bio's ``bi_end_io`` to an
1038c2ecf20Sopenharmony_ciinternal function that cleans up the bounce bio and ends the original bio.
1048c2ecf20Sopenharmony_ci
1058c2ecf20Sopenharmony_ciIf the bio is a ``READ`` bio, the bio's ``bi_end_io`` (and also ``bi_private``)
1068c2ecf20Sopenharmony_ciis saved and overwritten by ``blk-crypto-fallback`` to
1078c2ecf20Sopenharmony_ci``bio_crypto_fallback_decrypt_bio``.  The bio's ``bi_crypt_context`` is also
1088c2ecf20Sopenharmony_cioverwritten with ``NULL``, so that to the rest of the stack, the bio looks
1098c2ecf20Sopenharmony_cias if it was a regular bio that never had an encryption context specified.
1108c2ecf20Sopenharmony_ci``bio_crypto_fallback_decrypt_bio`` will decrypt the bio, restore the original
1118c2ecf20Sopenharmony_ci``bi_end_io`` (and also ``bi_private``) and end the bio again.
1128c2ecf20Sopenharmony_ci
1138c2ecf20Sopenharmony_ciRegardless of whether real inline encryption hardware is used or the
1148c2ecf20Sopenharmony_ciblk-crypto-fallback is used, the ciphertext written to disk (and hence the
1158c2ecf20Sopenharmony_cion-disk format of data) will be the same (assuming the hardware's implementation
1168c2ecf20Sopenharmony_ciof the algorithm being used adheres to spec and functions correctly).
1178c2ecf20Sopenharmony_ci
1188c2ecf20Sopenharmony_ciIf a ``request queue``'s inline encryption hardware claimed to support the
1198c2ecf20Sopenharmony_ciencryption context specified with a bio, then it will not be handled by the
1208c2ecf20Sopenharmony_ci``blk-crypto-fallback``. We will eventually reach a point in blk-mq when a
1218c2ecf20Sopenharmony_cistruct request needs to be allocated for that bio. At that point,
1228c2ecf20Sopenharmony_ciblk-mq tries to program the encryption context into the ``request_queue``'s
1238c2ecf20Sopenharmony_cikeyslot_manager, and obtain a keyslot, which it stores in its newly added
1248c2ecf20Sopenharmony_ci``keyslot`` field. This keyslot is released when the request is completed.
1258c2ecf20Sopenharmony_ci
1268c2ecf20Sopenharmony_ciWhen the first bio is added to a request, ``blk_crypto_rq_bio_prep`` is called,
1278c2ecf20Sopenharmony_ciwhich sets the request's ``crypt_ctx`` to a copy of the bio's
1288c2ecf20Sopenharmony_ci``bi_crypt_context``. bio_crypt_do_front_merge is called whenever a subsequent
1298c2ecf20Sopenharmony_cibio is merged to the front of the request, which updates the ``crypt_ctx`` of
1308c2ecf20Sopenharmony_cithe 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
1318c2ecf20Sopenharmony_cibio in its bio-list (blk-mq needs to be careful to maintain this invariant
1328c2ecf20Sopenharmony_ciduring bio and request merges).
1338c2ecf20Sopenharmony_ci
1348c2ecf20Sopenharmony_ciTo make it possible for inline encryption to work with request queue based
1358c2ecf20Sopenharmony_cilayered devices, when a request is cloned, its ``crypto fields`` are cloned as
1368c2ecf20Sopenharmony_ciwell. When the cloned request is submitted, blk-mq programs the
1378c2ecf20Sopenharmony_ci``bi_crypt_context`` of the request into the clone's request_queue's keyslot
1388c2ecf20Sopenharmony_cimanager, and stores the returned keyslot in the clone's ``keyslot``.
1398c2ecf20Sopenharmony_ci
1408c2ecf20Sopenharmony_ci
1418c2ecf20Sopenharmony_ciAPI presented to users of the block layer
1428c2ecf20Sopenharmony_ci=========================================
1438c2ecf20Sopenharmony_ci
1448c2ecf20Sopenharmony_ci``struct blk_crypto_key`` represents a crypto key (the raw key, size of the
1458c2ecf20Sopenharmony_cikey, the crypto algorithm to use, the data unit size to use, and the number of
1468c2ecf20Sopenharmony_cibytes required to represent data unit numbers that will be specified with the
1478c2ecf20Sopenharmony_ci``bi_crypt_context``).
1488c2ecf20Sopenharmony_ci
1498c2ecf20Sopenharmony_ci``blk_crypto_init_key`` allows upper layers to initialize such a
1508c2ecf20Sopenharmony_ci``blk_crypto_key``.
1518c2ecf20Sopenharmony_ci
1528c2ecf20Sopenharmony_ci``bio_crypt_set_ctx`` should be called on any bio that a user of
1538c2ecf20Sopenharmony_cithe block layer wants en/decrypted via inline encryption (or the
1548c2ecf20Sopenharmony_ciblk-crypto-fallback, if hardware support isn't available for the desired
1558c2ecf20Sopenharmony_cicrypto configuration). This function takes the ``blk_crypto_key`` and the
1568c2ecf20Sopenharmony_cidata unit number (DUN) to use when en/decrypting the bio.
1578c2ecf20Sopenharmony_ci
1588c2ecf20Sopenharmony_ci``blk_crypto_config_supported`` allows upper layers to query whether or not the
1598c2ecf20Sopenharmony_cian encryption context passed to request queue can be handled by blk-crypto
1608c2ecf20Sopenharmony_ci(either by real inline encryption hardware, or by the blk-crypto-fallback).
1618c2ecf20Sopenharmony_ciThis is useful e.g. when blk-crypto-fallback is disabled, and the upper layer
1628c2ecf20Sopenharmony_ciwants to use an algorithm that may not supported by hardware - this function
1638c2ecf20Sopenharmony_cilets the upper layer know ahead of time that the algorithm isn't supported,
1648c2ecf20Sopenharmony_ciand the upper layer can fallback to something else if appropriate.
1658c2ecf20Sopenharmony_ci
1668c2ecf20Sopenharmony_ci``blk_crypto_start_using_key`` - Upper layers must call this function on
1678c2ecf20Sopenharmony_ci``blk_crypto_key`` and a ``request_queue`` before using the key with any bio
1688c2ecf20Sopenharmony_ciheaded for that ``request_queue``. This function ensures that either the
1698c2ecf20Sopenharmony_cihardware supports the key's crypto settings, or the crypto API fallback has
1708c2ecf20Sopenharmony_citransforms for the needed mode allocated and ready to go. Note that this
1718c2ecf20Sopenharmony_cifunction may allocate an ``skcipher``, and must not be called from the data
1728c2ecf20Sopenharmony_cipath, since allocating ``skciphers`` from the data path can deadlock.
1738c2ecf20Sopenharmony_ci
1748c2ecf20Sopenharmony_ci``blk_crypto_evict_key`` *must* be called by upper layers before a
1758c2ecf20Sopenharmony_ci``blk_crypto_key`` is freed. Further, it *must* only be called only once
1768c2ecf20Sopenharmony_cithere are no more in-flight requests that use that ``blk_crypto_key``.
1778c2ecf20Sopenharmony_ci``blk_crypto_evict_key`` will ensure that a key is removed from any keyslots in
1788c2ecf20Sopenharmony_ciinline encryption hardware that the key might have been programmed into (or the blk-crypto-fallback).
1798c2ecf20Sopenharmony_ci
1808c2ecf20Sopenharmony_ciAPI presented to device drivers
1818c2ecf20Sopenharmony_ci===============================
1828c2ecf20Sopenharmony_ci
1838c2ecf20Sopenharmony_ciA :c:type:``struct blk_keyslot_manager`` should be set up by device drivers in
1848c2ecf20Sopenharmony_cithe ``request_queue`` of the device. The device driver needs to call
1858c2ecf20Sopenharmony_ci``blk_ksm_init`` on the ``blk_keyslot_manager``, which specifying the number of
1868c2ecf20Sopenharmony_cikeyslots supported by the hardware.
1878c2ecf20Sopenharmony_ci
1888c2ecf20Sopenharmony_ciThe device driver also needs to tell the KSM how to actually manipulate the
1898c2ecf20Sopenharmony_ciIE hardware in the device to do things like programming the crypto key into
1908c2ecf20Sopenharmony_cithe IE hardware into a particular keyslot. All this is achieved through the
1918c2ecf20Sopenharmony_cistruct blk_ksm_ll_ops field in the KSM that the device driver
1928c2ecf20Sopenharmony_cimust fill up after initing the ``blk_keyslot_manager``.
1938c2ecf20Sopenharmony_ci
1948c2ecf20Sopenharmony_ciThe KSM also handles runtime power management for the device when applicable
1958c2ecf20Sopenharmony_ci(e.g. when it wants to program a crypto key into the IE hardware, the device
1968c2ecf20Sopenharmony_cimust be runtime powered on) - so the device driver must also set the ``dev``
1978c2ecf20Sopenharmony_cifield in the ksm to point to the `struct device` for the KSM to use for runtime
1988c2ecf20Sopenharmony_cipower management.
1998c2ecf20Sopenharmony_ci
2008c2ecf20Sopenharmony_ci``blk_ksm_reprogram_all_keys`` can be called by device drivers if the device
2018c2ecf20Sopenharmony_cineeds each and every of its keyslots to be reprogrammed with the key it
2028c2ecf20Sopenharmony_ci"should have" at the point in time when the function is called. This is useful
2038c2ecf20Sopenharmony_cie.g. if a device loses all its keys on runtime power down/up.
2048c2ecf20Sopenharmony_ci
2058c2ecf20Sopenharmony_ci``blk_ksm_destroy`` should be called to free up all resources used by a keyslot
2068c2ecf20Sopenharmony_cimanager upon ``blk_ksm_init``, once the ``blk_keyslot_manager`` is no longer
2078c2ecf20Sopenharmony_cineeded.
2088c2ecf20Sopenharmony_ci
2098c2ecf20Sopenharmony_ci
2108c2ecf20Sopenharmony_ciLayered Devices
2118c2ecf20Sopenharmony_ci===============
2128c2ecf20Sopenharmony_ci
2138c2ecf20Sopenharmony_ciRequest queue based layered devices like dm-rq that wish to support IE need to
2148c2ecf20Sopenharmony_cicreate their own keyslot manager for their request queue, and expose whatever
2158c2ecf20Sopenharmony_cifunctionality they choose. When a layered device wants to pass a clone of that
2168c2ecf20Sopenharmony_cirequest to another ``request_queue``, blk-crypto will initialize and prepare the
2178c2ecf20Sopenharmony_ciclone as necessary - see ``blk_crypto_insert_cloned_request`` in
2188c2ecf20Sopenharmony_ci``blk-crypto.c``.
2198c2ecf20Sopenharmony_ci
2208c2ecf20Sopenharmony_ci
2218c2ecf20Sopenharmony_ciFuture Optimizations for layered devices
2228c2ecf20Sopenharmony_ci========================================
2238c2ecf20Sopenharmony_ci
2248c2ecf20Sopenharmony_ciCreating a keyslot manager for a layered device uses up memory for each
2258c2ecf20Sopenharmony_cikeyslot, and in general, a layered device merely passes the request on to a
2268c2ecf20Sopenharmony_ci"child" device, so the keyslots in the layered device itself are completely
2278c2ecf20Sopenharmony_ciunused, and don't need any refcounting or keyslot programming. We can instead
2288c2ecf20Sopenharmony_cidefine a new type of KSM; the "passthrough KSM", that layered devices can use
2298c2ecf20Sopenharmony_cito advertise an unlimited number of keyslots, and support for any encryption
2308c2ecf20Sopenharmony_cialgorithms they choose, while not actually using any memory for each keyslot.
2318c2ecf20Sopenharmony_ciAnother use case for the "passthrough KSM" is for IE devices that do not have a
2328c2ecf20Sopenharmony_cilimited number of keyslots.
2338c2ecf20Sopenharmony_ci
2348c2ecf20Sopenharmony_ci
2358c2ecf20Sopenharmony_ciInteraction between inline encryption and blk integrity
2368c2ecf20Sopenharmony_ci=======================================================
2378c2ecf20Sopenharmony_ci
2388c2ecf20Sopenharmony_ciAt the time of this patch, there is no real hardware that supports both these
2398c2ecf20Sopenharmony_cifeatures. However, these features do interact with each other, and it's not
2408c2ecf20Sopenharmony_cicompletely trivial to make them both work together properly. In particular,
2418c2ecf20Sopenharmony_ciwhen a WRITE bio wants to use inline encryption on a device that supports both
2428c2ecf20Sopenharmony_cifeatures, the bio will have an encryption context specified, after which
2438c2ecf20Sopenharmony_ciits integrity information is calculated (using the plaintext data, since
2448c2ecf20Sopenharmony_cithe encryption will happen while data is being written), and the data and
2458c2ecf20Sopenharmony_ciintegrity info is sent to the device. Obviously, the integrity info must be
2468c2ecf20Sopenharmony_civerified before the data is encrypted. After the data is encrypted, the device
2478c2ecf20Sopenharmony_cimust not store the integrity info that it received with the plaintext data
2488c2ecf20Sopenharmony_cisince that might reveal information about the plaintext data. As such, it must
2498c2ecf20Sopenharmony_cire-generate the integrity info from the ciphertext data and store that on disk
2508c2ecf20Sopenharmony_ciinstead. Another issue with storing the integrity info of the plaintext data is
2518c2ecf20Sopenharmony_cithat it changes the on disk format depending on whether hardware inline
2528c2ecf20Sopenharmony_ciencryption support is present or the kernel crypto API fallback is used (since
2538c2ecf20Sopenharmony_ciif the fallback is used, the device will receive the integrity info of the
2548c2ecf20Sopenharmony_ciciphertext, not that of the plaintext).
2558c2ecf20Sopenharmony_ci
2568c2ecf20Sopenharmony_ciBecause there isn't any real hardware yet, it seems prudent to assume that
2578c2ecf20Sopenharmony_cihardware implementations might not implement both features together correctly,
2588c2ecf20Sopenharmony_ciand disallow the combination for now. Whenever a device supports integrity, the
2598c2ecf20Sopenharmony_cikernel will pretend that the device does not support hardware inline encryption
2608c2ecf20Sopenharmony_ci(by essentially setting the keyslot manager in the request_queue of the device
2618c2ecf20Sopenharmony_cito NULL). When the crypto API fallback is enabled, this means that all bios with
2628c2ecf20Sopenharmony_ciand encryption context will use the fallback, and IO will complete as usual.
2638c2ecf20Sopenharmony_ciWhen the fallback is disabled, a bio with an encryption context will be failed.
264