cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

inline-encryption.rst (17074B)


      1.. SPDX-License-Identifier: GPL-2.0
      2
      3.. _inline_encryption:
      4
      5=================
      6Inline Encryption
      7=================
      8
      9Background
     10==========
     11
     12Inline encryption hardware sits logically between memory and disk, and can
     13en/decrypt data as it goes in/out of the disk.  For each I/O request, software
     14can control exactly how the inline encryption hardware will en/decrypt the data
     15in terms of key, algorithm, data unit size (the granularity of en/decryption),
     16and data unit number (a value that determines the initialization vector(s)).
     17
     18Some inline encryption hardware accepts all encryption parameters including raw
     19keys directly in low-level I/O requests.  However, most inline encryption
     20hardware instead has a fixed number of "keyslots" and requires that the key,
     21algorithm, and data unit size first be programmed into a keyslot.  Each
     22low-level I/O request then just contains a keyslot index and data unit number.
     23
     24Note that inline encryption hardware is very different from traditional crypto
     25accelerators, which are supported through the kernel crypto API.  Traditional
     26crypto accelerators operate on memory regions, whereas inline encryption
     27hardware operates on I/O requests.  Thus, inline encryption hardware needs to be
     28managed by the block layer, not the kernel crypto API.
     29
     30Inline encryption hardware is also very different from "self-encrypting drives",
     31such as those based on the TCG Opal or ATA Security standards.  Self-encrypting
     32drives don't provide fine-grained control of encryption and provide no way to
     33verify the correctness of the resulting ciphertext.  Inline encryption hardware
     34provides fine-grained control of encryption, including the choice of key and
     35initialization vector for each sector, and can be tested for correctness.
     36
     37Objective
     38=========
     39
     40We want to support inline encryption in the kernel.  To make testing easier, we
     41also want support for falling back to the kernel crypto API when actual inline
     42encryption hardware is absent.  We also want inline encryption to work with
     43layered devices like device-mapper and loopback (i.e. we want to be able to use
     44the inline encryption hardware of the underlying devices if present, or else
     45fall back to crypto API en/decryption).
     46
     47Constraints and notes
     48=====================
     49
     50- We need a way for upper layers (e.g. filesystems) to specify an encryption
     51  context to use for en/decrypting a bio, and device drivers (e.g. UFSHCD) need
     52  to be able to use that encryption context when they process the request.
     53  Encryption contexts also introduce constraints on bio merging; the block layer
     54  needs to be aware of these constraints.
     55
     56- Different inline encryption hardware has different supported algorithms,
     57  supported data unit sizes, maximum data unit numbers, etc.  We call these
     58  properties the "crypto capabilities".  We need a way for device drivers to
     59  advertise crypto capabilities to upper layers in a generic way.
     60
     61- Inline encryption hardware usually (but not always) requires that keys be
     62  programmed into keyslots before being used.  Since programming keyslots may be
     63  slow and there may not be very many keyslots, we shouldn't just program the
     64  key for every I/O request, but rather keep track of which keys are in the
     65  keyslots and reuse an already-programmed keyslot when possible.
     66
     67- Upper layers typically define a specific end-of-life for crypto keys, e.g.
     68  when an encrypted directory is locked or when a crypto mapping is torn down.
     69  At these times, keys are wiped from memory.  We must provide a way for upper
     70  layers to also evict keys from any keyslots they are present in.
     71
     72- When possible, device-mapper devices must be able to pass through the inline
     73  encryption support of their underlying devices.  However, it doesn't make
     74  sense for device-mapper devices to have keyslots themselves.
     75
     76Basic design
     77============
     78
     79We introduce ``struct blk_crypto_key`` to represent an inline encryption key and
     80how it will be used.  This includes the actual bytes of the key; the size of the
     81key; the algorithm and data unit size the key will be used with; and the number
     82of bytes needed to represent the maximum data unit number the key will be used
     83with.
     84
     85We introduce ``struct bio_crypt_ctx`` to represent an encryption context.  It
     86contains a data unit number and a pointer to a blk_crypto_key.  We add pointers
     87to a bio_crypt_ctx to ``struct bio`` and ``struct request``; this allows users
     88of the block layer (e.g. filesystems) to provide an encryption context when
     89creating a bio and have it be passed down the stack for processing by the block
     90layer and device drivers.  Note that the encryption context doesn't explicitly
     91say whether to encrypt or decrypt, as that is implicit from the direction of the
     92bio; WRITE means encrypt, and READ means decrypt.
     93
     94We also introduce ``struct blk_crypto_profile`` to contain all generic inline
     95encryption-related state for a particular inline encryption device.  The
     96blk_crypto_profile serves as the way that drivers for inline encryption hardware
     97advertise their crypto capabilities and provide certain functions (e.g.,
     98functions to program and evict keys) to upper layers.  Each device driver that
     99wants to support inline encryption will construct a blk_crypto_profile, then
    100associate it with the disk's request_queue.
    101
    102The blk_crypto_profile also manages the hardware's keyslots, when applicable.
    103This happens in the block layer, so that users of the block layer can just
    104specify encryption contexts and don't need to know about keyslots at all, nor do
    105device drivers need to care about most details of keyslot management.
    106
    107Specifically, for each keyslot, the block layer (via the blk_crypto_profile)
    108keeps track of which blk_crypto_key that keyslot contains (if any), and how many
    109in-flight I/O requests are using it.  When the block layer creates a
    110``struct request`` for a bio that has an encryption context, it grabs a keyslot
    111that already contains the key if possible.  Otherwise it waits for an idle
    112keyslot (a keyslot that isn't in-use by any I/O), then programs the key into the
    113least-recently-used idle keyslot using the function the device driver provided.
    114In both cases, the resulting keyslot is stored in the ``crypt_keyslot`` field of
    115the request, where it is then accessible to device drivers and is released after
    116the request completes.
    117
    118``struct request`` also contains a pointer to the original bio_crypt_ctx.
    119Requests can be built from multiple bios, and the block layer must take the
    120encryption context into account when trying to merge bios and requests.  For two
    121bios/requests to be merged, they must have compatible encryption contexts: both
    122unencrypted, or both encrypted with the same key and contiguous data unit
    123numbers.  Only the encryption context for the first bio in a request is
    124retained, since the remaining bios have been verified to be merge-compatible
    125with the first bio.
    126
    127To make it possible for inline encryption to work with request_queue based
    128layered devices, when a request is cloned, its encryption context is cloned as
    129well.  When the cloned request is submitted, it is then processed as usual; this
    130includes getting a keyslot from the clone's target device if needed.
    131
    132blk-crypto-fallback
    133===================
    134
    135It is desirable for the inline encryption support of upper layers (e.g.
    136filesystems) to be testable without real inline encryption hardware, and
    137likewise for the block layer's keyslot management logic.  It is also desirable
    138to allow upper layers to just always use inline encryption rather than have to
    139implement encryption in multiple ways.
    140
    141Therefore, we also introduce *blk-crypto-fallback*, which is an implementation
    142of inline encryption using the kernel crypto API.  blk-crypto-fallback is built
    143into the block layer, so it works on any block device without any special setup.
    144Essentially, when a bio with an encryption context is submitted to a
    145request_queue that doesn't support that encryption context, the block layer will
    146handle en/decryption of the bio using blk-crypto-fallback.
    147
    148For encryption, the data cannot be encrypted in-place, as callers usually rely
    149on it being unmodified.  Instead, blk-crypto-fallback allocates bounce pages,
    150fills a new bio with those bounce pages, encrypts the data into those bounce
    151pages, and submits that "bounce" bio.  When the bounce bio completes,
    152blk-crypto-fallback completes the original bio.  If the original bio is too
    153large, multiple bounce bios may be required; see the code for details.
    154
    155For decryption, blk-crypto-fallback "wraps" the bio's completion callback
    156(``bi_complete``) and private data (``bi_private``) with its own, unsets the
    157bio's encryption context, then submits the bio.  If the read completes
    158successfully, blk-crypto-fallback restores the bio's original completion
    159callback and private data, then decrypts the bio's data in-place using the
    160kernel crypto API.  Decryption happens from a workqueue, as it may sleep.
    161Afterwards, blk-crypto-fallback completes the bio.
    162
    163In both cases, the bios that blk-crypto-fallback submits no longer have an
    164encryption context.  Therefore, lower layers only see standard unencrypted I/O.
    165
    166blk-crypto-fallback also defines its own blk_crypto_profile and has its own
    167"keyslots"; its keyslots contain ``struct crypto_skcipher`` objects.  The reason
    168for this is twofold.  First, it allows the keyslot management logic to be tested
    169without actual inline encryption hardware.  Second, similar to actual inline
    170encryption hardware, the crypto API doesn't accept keys directly in requests but
    171rather requires that keys be set ahead of time, and setting keys can be
    172expensive; moreover, allocating a crypto_skcipher can't happen on the I/O path
    173at all due to the locks it takes.  Therefore, the concept of keyslots still
    174makes sense for blk-crypto-fallback.
    175
    176Note that regardless of whether real inline encryption hardware or
    177blk-crypto-fallback is used, the ciphertext written to disk (and hence the
    178on-disk format of data) will be the same (assuming that both the inline
    179encryption hardware's implementation and the kernel crypto API's implementation
    180of the algorithm being used adhere to spec and function correctly).
    181
    182blk-crypto-fallback is optional and is controlled by the
    183``CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK`` kernel configuration option.
    184
    185API presented to users of the block layer
    186=========================================
    187
    188``blk_crypto_config_supported()`` allows users to check ahead of time whether
    189inline encryption with particular crypto settings will work on a particular
    190request_queue -- either via hardware or via blk-crypto-fallback.  This function
    191takes in a ``struct blk_crypto_config`` which is like blk_crypto_key, but omits
    192the actual bytes of the key and instead just contains the algorithm, data unit
    193size, etc.  This function can be useful if blk-crypto-fallback is disabled.
    194
    195``blk_crypto_init_key()`` allows users to initialize a blk_crypto_key.
    196
    197Users must call ``blk_crypto_start_using_key()`` before actually starting to use
    198a blk_crypto_key on a request_queue (even if ``blk_crypto_config_supported()``
    199was called earlier).  This is needed to initialize blk-crypto-fallback if it
    200will be needed.  This must not be called from the data path, as this may have to
    201allocate resources, which may deadlock in that case.
    202
    203Next, to attach an encryption context to a bio, users should call
    204``bio_crypt_set_ctx()``.  This function allocates a bio_crypt_ctx and attaches
    205it to a bio, given the blk_crypto_key and the data unit number that will be used
    206for en/decryption.  Users don't need to worry about freeing the bio_crypt_ctx
    207later, as that happens automatically when the bio is freed or reset.
    208
    209Finally, when done using inline encryption with a blk_crypto_key on a
    210request_queue, users must call ``blk_crypto_evict_key()``.  This ensures that
    211the key is evicted from all keyslots it may be programmed into and unlinked from
    212any kernel data structures it may be linked into.
    213
    214In summary, for users of the block layer, the lifecycle of a blk_crypto_key is
    215as follows:
    216
    2171. ``blk_crypto_config_supported()`` (optional)
    2182. ``blk_crypto_init_key()``
    2193. ``blk_crypto_start_using_key()``
    2204. ``bio_crypt_set_ctx()`` (potentially many times)
    2215. ``blk_crypto_evict_key()`` (after all I/O has completed)
    2226. Zeroize the blk_crypto_key (this has no dedicated function)
    223
    224If a blk_crypto_key is being used on multiple request_queues, then
    225``blk_crypto_config_supported()`` (if used), ``blk_crypto_start_using_key()``,
    226and ``blk_crypto_evict_key()`` must be called on each request_queue.
    227
    228API presented to device drivers
    229===============================
    230
    231A device driver that wants to support inline encryption must set up a
    232blk_crypto_profile in the request_queue of its device.  To do this, it first
    233must call ``blk_crypto_profile_init()`` (or its resource-managed variant
    234``devm_blk_crypto_profile_init()``), providing the number of keyslots.
    235
    236Next, it must advertise its crypto capabilities by setting fields in the
    237blk_crypto_profile, e.g. ``modes_supported`` and ``max_dun_bytes_supported``.
    238
    239It then must set function pointers in the ``ll_ops`` field of the
    240blk_crypto_profile to tell upper layers how to control the inline encryption
    241hardware, e.g. how to program and evict keyslots.  Most drivers will need to
    242implement ``keyslot_program`` and ``keyslot_evict``.  For details, see the
    243comments for ``struct blk_crypto_ll_ops``.
    244
    245Once the driver registers a blk_crypto_profile with a request_queue, I/O
    246requests the driver receives via that queue may have an encryption context.  All
    247encryption contexts will be compatible with the crypto capabilities declared in
    248the blk_crypto_profile, so drivers don't need to worry about handling
    249unsupported requests.  Also, if a nonzero number of keyslots was declared in the
    250blk_crypto_profile, then all I/O requests that have an encryption context will
    251also have a keyslot which was already programmed with the appropriate key.
    252
    253If the driver implements runtime suspend and its blk_crypto_ll_ops don't work
    254while the device is runtime-suspended, then the driver must also set the ``dev``
    255field of the blk_crypto_profile to point to the ``struct device`` that will be
    256resumed before any of the low-level operations are called.
    257
    258If there are situations where the inline encryption hardware loses the contents
    259of its keyslots, e.g. device resets, the driver must handle reprogramming the
    260keyslots.  To do this, the driver may call ``blk_crypto_reprogram_all_keys()``.
    261
    262Finally, if the driver used ``blk_crypto_profile_init()`` instead of
    263``devm_blk_crypto_profile_init()``, then it is responsible for calling
    264``blk_crypto_profile_destroy()`` when the crypto profile is no longer needed.
    265
    266Layered Devices
    267===============
    268
    269Request queue based layered devices like dm-rq that wish to support inline
    270encryption need to create their own blk_crypto_profile for their request_queue,
    271and expose whatever functionality they choose. When a layered device wants to
    272pass a clone of that request to another request_queue, blk-crypto will
    273initialize and prepare the clone as necessary; see
    274``blk_crypto_insert_cloned_request()``.
    275
    276Interaction between inline encryption and blk integrity
    277=======================================================
    278
    279At the time of this patch, there is no real hardware that supports both these
    280features. However, these features do interact with each other, and it's not
    281completely trivial to make them both work together properly. In particular,
    282when a WRITE bio wants to use inline encryption on a device that supports both
    283features, the bio will have an encryption context specified, after which
    284its integrity information is calculated (using the plaintext data, since
    285the encryption will happen while data is being written), and the data and
    286integrity info is sent to the device. Obviously, the integrity info must be
    287verified before the data is encrypted. After the data is encrypted, the device
    288must not store the integrity info that it received with the plaintext data
    289since that might reveal information about the plaintext data. As such, it must
    290re-generate the integrity info from the ciphertext data and store that on disk
    291instead. Another issue with storing the integrity info of the plaintext data is
    292that it changes the on disk format depending on whether hardware inline
    293encryption support is present or the kernel crypto API fallback is used (since
    294if the fallback is used, the device will receive the integrity info of the
    295ciphertext, not that of the plaintext).
    296
    297Because there isn't any real hardware yet, it seems prudent to assume that
    298hardware implementations might not implement both features together correctly,
    299and disallow the combination for now. Whenever a device supports integrity, the
    300kernel will pretend that the device does not support hardware inline encryption
    301(by setting the blk_crypto_profile in the request_queue of the device to NULL).
    302When the crypto API fallback is enabled, this means that all bios with and
    303encryption context will use the fallback, and IO will complete as usual.  When
    304the fallback is disabled, a bio with an encryption context will be failed.