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