sphinx.addnodesdocument)}( rawsourcechildren]( translations LanguagesNode)}(hhh](h pending_xref)}(hhh]docutils.nodesTextChinese (Simplified)}parenthsba attributes}(ids]classes]names]dupnames]backrefs] refdomainstdreftypedoc reftarget+/translations/zh_CN/block/inline-encryptionmodnameN classnameN refexplicitutagnamehhh ubh)}(hhh]hChinese (Traditional)}hh2sbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget+/translations/zh_TW/block/inline-encryptionmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hItalian}hhFsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget+/translations/it_IT/block/inline-encryptionmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hJapanese}hhZsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget+/translations/ja_JP/block/inline-encryptionmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hKorean}hhnsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget+/translations/ko_KR/block/inline-encryptionmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hSpanish}hhsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget+/translations/sp_SP/block/inline-encryptionmodnameN classnameN refexplicituh1hhh ubeh}(h]h ]h"]h$]h&]current_languageEnglishuh1h hh _documenthsourceNlineNubhcomment)}(h SPDX-License-Identifier: GPL-2.0h]h SPDX-License-Identifier: GPL-2.0}hhsbah}(h]h ]h"]h$]h&] xml:spacepreserveuh1hhhhhhE/var/lib/git/docbuild/linux/Documentation/block/inline-encryption.rsthKubhtarget)}(h.. _inline_encryption:h]h}(h]h ]h"]h$]h&]refidinline-encryptionuh1hhKhhhhhhubhsection)}(hhh](htitle)}(hInline Encryptionh]hInline Encryption}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhhhhhKubh)}(hhh](h)}(h Backgroundh]h Background}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhhhhhK ubh paragraph)}(hXInline encryption hardware sits logically between memory and disk, and can en/decrypt data as it goes in/out of the disk. For each I/O request, software can control exactly how the inline encryption hardware will en/decrypt the data in terms of key, algorithm, data unit size (the granularity of en/decryption), and data unit number (a value that determines the initialization vector(s)).h]hXInline encryption hardware sits logically between memory and disk, and can en/decrypt data as it goes in/out of the disk. For each I/O request, software can control exactly how the inline encryption hardware will en/decrypt the data in terms of key, algorithm, data unit size (the granularity of en/decryption), and data unit number (a value that determines the initialization vector(s)).}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK hhhhubh)}(hX}Some inline encryption hardware accepts all encryption parameters including raw keys directly in low-level I/O requests. However, most inline encryption hardware instead has a fixed number of "keyslots" and requires that the key, algorithm, and data unit size first be programmed into a keyslot. Each low-level I/O request then just contains a keyslot index and data unit number.h]hXSome inline encryption hardware accepts all encryption parameters including raw keys directly in low-level I/O requests. However, most inline encryption hardware instead has a fixed number of “keyslots” and requires that the key, algorithm, and data unit size first be programmed into a keyslot. Each low-level I/O request then just contains a keyslot index and data unit number.}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh)}(hXmNote that inline encryption hardware is very different from traditional crypto accelerators, which are supported through the kernel crypto API. Traditional crypto accelerators operate on memory regions, whereas inline encryption hardware operates on I/O requests. Thus, inline encryption hardware needs to be managed by the block layer, not the kernel crypto API.h]hXmNote that inline encryption hardware is very different from traditional crypto accelerators, which are supported through the kernel crypto API. Traditional crypto accelerators operate on memory regions, whereas inline encryption hardware operates on I/O requests. Thus, inline encryption hardware needs to be managed by the block layer, not the kernel crypto API.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh)}(hXInline encryption hardware is also very different from "self-encrypting drives", such as those based on the TCG Opal or ATA Security standards. Self-encrypting drives don't provide fine-grained control of encryption and provide no way to verify the correctness of the resulting ciphertext. Inline encryption hardware provides fine-grained control of encryption, including the choice of key and initialization vector for each sector, and can be tested for correctness.h]hXInline encryption hardware is also very different from “self-encrypting drives”, such as those based on the TCG Opal or ATA Security standards. Self-encrypting drives don’t provide fine-grained control of encryption and provide no way to verify the correctness of the resulting ciphertext. Inline encryption hardware provides fine-grained control of encryption, including the choice of key and initialization vector for each sector, and can be tested for correctness.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhhhhubeh}(h] backgroundah ]h"] backgroundah$]h&]uh1hhhhhhhhK ubh)}(hhh](h)}(h Objectiveh]h Objective}(hj-hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj*hhhhhK&ubh)}(hXWe want to support inline encryption in the kernel. To make testing easier, we also want support for falling back to the kernel crypto API when actual inline encryption hardware is absent. We also want inline encryption to work with layered devices like device-mapper and loopback (i.e. we want to be able to use the inline encryption hardware of the underlying devices if present, or else fall back to crypto API en/decryption).h]hXWe want to support inline encryption in the kernel. To make testing easier, we also want support for falling back to the kernel crypto API when actual inline encryption hardware is absent. We also want inline encryption to work with layered devices like device-mapper and loopback (i.e. we want to be able to use the inline encryption hardware of the underlying devices if present, or else fall back to crypto API en/decryption).}(hj;hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK(hj*hhubeh}(h] objectiveah ]h"] objectiveah$]h&]uh1hhhhhhhhK&ubh)}(hhh](h)}(hConstraints and notesh]hConstraints and notes}(hjThhhNhNubah}(h]h ]h"]h$]h&]uh1hhjQhhhhhK0ubh bullet_list)}(hhh](h list_item)}(hXYWe need a way for upper layers (e.g. filesystems) to specify an encryption context to use for en/decrypting a bio, and device drivers (e.g. UFSHCD) need to be able to use that encryption context when they process the request. Encryption contexts also introduce constraints on bio merging; the block layer needs to be aware of these constraints. h]h)}(hXXWe need a way for upper layers (e.g. filesystems) to specify an encryption context to use for en/decrypting a bio, and device drivers (e.g. UFSHCD) need to be able to use that encryption context when they process the request. Encryption contexts also introduce constraints on bio merging; the block layer needs to be aware of these constraints.h]hXXWe need a way for upper layers (e.g. filesystems) to specify an encryption context to use for en/decrypting a bio, and device drivers (e.g. UFSHCD) need to be able to use that encryption context when they process the request. Encryption contexts also introduce constraints on bio merging; the block layer needs to be aware of these constraints.}(hjmhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK2hjiubah}(h]h ]h"]h$]h&]uh1jghjdhhhhhNubjh)}(hXDifferent inline encryption hardware has different supported algorithms, supported data unit sizes, maximum data unit numbers, etc. We call these properties the "crypto capabilities". We need a way for device drivers to advertise crypto capabilities to upper layers in a generic way. h]h)}(hXDifferent inline encryption hardware has different supported algorithms, supported data unit sizes, maximum data unit numbers, etc. We call these properties the "crypto capabilities". We need a way for device drivers to advertise crypto capabilities to upper layers in a generic way.h]hX!Different inline encryption hardware has different supported algorithms, supported data unit sizes, maximum data unit numbers, etc. We call these properties the “crypto capabilities”. We need a way for device drivers to advertise crypto capabilities to upper layers in a generic way.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK8hjubah}(h]h ]h"]h$]h&]uh1jghjdhhhhhNubjh)}(hXoInline encryption hardware usually (but not always) requires that keys be programmed into keyslots before being used. Since programming keyslots may be slow and there may not be very many keyslots, we shouldn't just program the key for every I/O request, but rather keep track of which keys are in the keyslots and reuse an already-programmed keyslot when possible. h]h)}(hXnInline encryption hardware usually (but not always) requires that keys be programmed into keyslots before being used. Since programming keyslots may be slow and there may not be very many keyslots, we shouldn't just program the key for every I/O request, but rather keep track of which keys are in the keyslots and reuse an already-programmed keyslot when possible.h]hXpInline encryption hardware usually (but not always) requires that keys be programmed into keyslots before being used. Since programming keyslots may be slow and there may not be very many keyslots, we shouldn’t just program the key for every I/O request, but rather keep track of which keys are in the keyslots and reuse an already-programmed keyslot when possible.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK=hjubah}(h]h ]h"]h$]h&]uh1jghjdhhhhhNubjh)}(hX&Upper layers typically define a specific end-of-life for crypto keys, e.g. when an encrypted directory is locked or when a crypto mapping is torn down. At these times, keys are wiped from memory. We must provide a way for upper layers to also evict keys from any keyslots they are present in. h]h)}(hX%Upper layers typically define a specific end-of-life for crypto keys, e.g. when an encrypted directory is locked or when a crypto mapping is torn down. At these times, keys are wiped from memory. We must provide a way for upper layers to also evict keys from any keyslots they are present in.h]hX%Upper layers typically define a specific end-of-life for crypto keys, e.g. when an encrypted directory is locked or when a crypto mapping is torn down. At these times, keys are wiped from memory. We must provide a way for upper layers to also evict keys from any keyslots they are present in.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKChjubah}(h]h ]h"]h$]h&]uh1jghjdhhhhhNubjh)}(hWhen possible, device-mapper devices must be able to pass through the inline encryption support of their underlying devices. However, it doesn't make sense for device-mapper devices to have keyslots themselves. h]h)}(hWhen possible, device-mapper devices must be able to pass through the inline encryption support of their underlying devices. However, it doesn't make sense for device-mapper devices to have keyslots themselves.h]hWhen possible, device-mapper devices must be able to pass through the inline encryption support of their underlying devices. However, it doesn’t make sense for device-mapper devices to have keyslots themselves.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKHhjubah}(h]h ]h"]h$]h&]uh1jghjdhhhhhNubeh}(h]h ]h"]h$]h&]bullet-uh1jbhhhK2hjQhhubeh}(h]constraints-and-notesah ]h"]constraints and notesah$]h&]uh1hhhhhhhhK0ubh)}(hhh](h)}(h Basic designh]h Basic design}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhKMubh)}(hXuWe introduce ``struct blk_crypto_key`` to represent an inline encryption key and how it will be used. This includes the type of the key (raw or hardware-wrapped); the actual bytes of the key; the size of the key; the algorithm and data unit size the key will be used with; and the number of bytes needed to represent the maximum data unit number the key will be used with.h](h We introduce }(hjhhhNhNubhliteral)}(h``struct blk_crypto_key``h]hstruct blk_crypto_key}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j hjubhXO to represent an inline encryption key and how it will be used. This includes the type of the key (raw or hardware-wrapped); the actual bytes of the key; the size of the key; the algorithm and data unit size the key will be used with; and the number of bytes needed to represent the maximum data unit number the key will be used with.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKOhjhhubh)}(hXZWe introduce ``struct bio_crypt_ctx`` to represent an encryption context. It contains a data unit number and a pointer to a blk_crypto_key. We add pointers to a bio_crypt_ctx to ``struct bio`` and ``struct request``; this allows users of the block layer (e.g. filesystems) to provide an encryption context when creating a bio and have it be passed down the stack for processing by the block layer and device drivers. Note that the encryption context doesn't explicitly say whether to encrypt or decrypt, as that is implicit from the direction of the bio; WRITE means encrypt, and READ means decrypt.h](h We introduce }(hj$hhhNhNubj )}(h``struct bio_crypt_ctx``h]hstruct bio_crypt_ctx}(hj,hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj$ubh to represent an encryption context. It contains a data unit number and a pointer to a blk_crypto_key. We add pointers to a bio_crypt_ctx to }(hj$hhhNhNubj )}(h``struct bio``h]h struct bio}(hj>hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj$ubh and }(hj$hhhNhNubj )}(h``struct request``h]hstruct request}(hjPhhhNhNubah}(h]h ]h"]h$]h&]uh1j hj$ubhX; this allows users of the block layer (e.g. filesystems) to provide an encryption context when creating a bio and have it be passed down the stack for processing by the block layer and device drivers. Note that the encryption context doesn’t explicitly say whether to encrypt or decrypt, as that is implicit from the direction of the bio; WRITE means encrypt, and READ means decrypt.}(hj$hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKUhjhhubh)}(hXWe also introduce ``struct blk_crypto_profile`` to contain all generic inline encryption-related state for a particular inline encryption device. The blk_crypto_profile serves as the way that drivers for inline encryption hardware advertise their crypto capabilities and provide certain functions (e.g., functions to program and evict keys) to upper layers. Each device driver that wants to support inline encryption will construct a blk_crypto_profile, then associate it with the disk's request_queue.h](hWe also introduce }(hjhhhhNhNubj )}(h``struct blk_crypto_profile``h]hstruct blk_crypto_profile}(hjphhhNhNubah}(h]h ]h"]h$]h&]uh1j hjhubhX to contain all generic inline encryption-related state for a particular inline encryption device. The blk_crypto_profile serves as the way that drivers for inline encryption hardware advertise their crypto capabilities and provide certain functions (e.g., functions to program and evict keys) to upper layers. Each device driver that wants to support inline encryption will construct a blk_crypto_profile, then associate it with the disk’s request_queue.}(hjhhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK^hjhhubh)}(hX/The blk_crypto_profile also manages the hardware's keyslots, when applicable. This happens in the block layer, so that users of the block layer can just specify encryption contexts and don't need to know about keyslots at all, nor do device drivers need to care about most details of keyslot management.h]hX3The blk_crypto_profile also manages the hardware’s keyslots, when applicable. This happens in the block layer, so that users of the block layer can just specify encryption contexts and don’t need to know about keyslots at all, nor do device drivers need to care about most details of keyslot management.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKfhjhhubh)}(hXSpecifically, for each keyslot, the block layer (via the blk_crypto_profile) keeps track of which blk_crypto_key that keyslot contains (if any), and how many in-flight I/O requests are using it. When the block layer creates a ``struct request`` for a bio that has an encryption context, it grabs a keyslot that already contains the key if possible. Otherwise it waits for an idle keyslot (a keyslot that isn't in-use by any I/O), then programs the key into the least-recently-used idle keyslot using the function the device driver provided. In both cases, the resulting keyslot is stored in the ``crypt_keyslot`` field of the request, where it is then accessible to device drivers and is released after the request completes.h](hSpecifically, for each keyslot, the block layer (via the blk_crypto_profile) keeps track of which blk_crypto_key that keyslot contains (if any), and how many in-flight I/O requests are using it. When the block layer creates a }(hjhhhNhNubj )}(h``struct request``h]hstruct request}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j hjubhXb for a bio that has an encryption context, it grabs a keyslot that already contains the key if possible. Otherwise it waits for an idle keyslot (a keyslot that isn’t in-use by any I/O), then programs the key into the least-recently-used idle keyslot using the function the device driver provided. In both cases, the resulting keyslot is stored in the }(hjhhhNhNubj )}(h``crypt_keyslot``h]h crypt_keyslot}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j hjubhq field of the request, where it is then accessible to device drivers and is released after the request completes.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKkhjhhubh)}(hX)``struct request`` also contains a pointer to the original bio_crypt_ctx. Requests can be built from multiple bios, and the block layer must take the encryption context into account when trying to merge bios and requests. For two bios/requests to be merged, they must have compatible encryption contexts: both unencrypted, or both encrypted with the same key and contiguous data unit numbers. Only the encryption context for the first bio in a request is retained, since the remaining bios have been verified to be merge-compatible with the first bio.h](j )}(h``struct request``h]hstruct request}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j hjubhX also contains a pointer to the original bio_crypt_ctx. Requests can be built from multiple bios, and the block layer must take the encryption context into account when trying to merge bios and requests. For two bios/requests to be merged, they must have compatible encryption contexts: both unencrypted, or both encrypted with the same key and contiguous data unit numbers. Only the encryption context for the first bio in a request is retained, since the remaining bios have been verified to be merge-compatible with the first bio.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKvhjhhubh)}(hX/To make it possible for inline encryption to work with request_queue based layered devices, when a request is cloned, its encryption context is cloned as well. When the cloned request is submitted, it is then processed as usual; this includes getting a keyslot from the clone's target device if needed.h]hX1To make it possible for inline encryption to work with request_queue based layered devices, when a request is cloned, its encryption context is cloned as well. When the cloned request is submitted, it is then processed as usual; this includes getting a keyslot from the clone’s target device if needed.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubeh}(h] basic-designah ]h"] basic designah$]h&]uh1hhhhhhhhKMubh)}(hhh](h)}(hblk-crypto-fallbackh]hblk-crypto-fallback}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhKubh)}(hXUIt is desirable for the inline encryption support of upper layers (e.g. filesystems) to be testable without real inline encryption hardware, and likewise for the block layer's keyslot management logic. It is also desirable to allow upper layers to just always use inline encryption rather than have to implement encryption in multiple ways.h]hXWIt is desirable for the inline encryption support of upper layers (e.g. filesystems) to be testable without real inline encryption hardware, and likewise for the block layer’s keyslot management logic. It is also desirable to allow upper layers to just always use inline encryption rather than have to implement encryption in multiple ways.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hXTherefore, we also introduce *blk-crypto-fallback*, which is an implementation of inline encryption using the kernel crypto API. blk-crypto-fallback is built into the block layer, so it works on any block device without any special setup. Essentially, when a bio with an encryption context is submitted to a block_device that doesn't support that encryption context, the block layer will handle en/decryption of the bio using blk-crypto-fallback.h](hTherefore, we also introduce }(hjhhhNhNubhemphasis)}(h*blk-crypto-fallback*h]hblk-crypto-fallback}(hj#hhhNhNubah}(h]h ]h"]h$]h&]uh1j!hjubhX, which is an implementation of inline encryption using the kernel crypto API. blk-crypto-fallback is built into the block layer, so it works on any block device without any special setup. Essentially, when a bio with an encryption context is submitted to a block_device that doesn’t support that encryption context, the block layer will handle en/decryption of the bio using blk-crypto-fallback.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hXFor encryption, the data cannot be encrypted in-place, as callers usually rely on it being unmodified. Instead, blk-crypto-fallback allocates bounce pages, fills a new bio with those bounce pages, encrypts the data into those bounce pages, and submits that "bounce" bio. When the bounce bio completes, blk-crypto-fallback completes the original bio. If the original bio is too large, multiple bounce bios may be required; see the code for details.h]hXFor encryption, the data cannot be encrypted in-place, as callers usually rely on it being unmodified. Instead, blk-crypto-fallback allocates bounce pages, fills a new bio with those bounce pages, encrypts the data into those bounce pages, and submits that “bounce” bio. When the bounce bio completes, blk-crypto-fallback completes the original bio. If the original bio is too large, multiple bounce bios may be required; see the code for details.}(hj;hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hXFor decryption, blk-crypto-fallback "wraps" the bio's completion callback (``bi_complete``) and private data (``bi_private``) with its own, unsets the bio's encryption context, then submits the bio. If the read completes successfully, blk-crypto-fallback restores the bio's original completion callback and private data, then decrypts the bio's data in-place using the kernel crypto API. Decryption happens from a workqueue, as it may sleep. Afterwards, blk-crypto-fallback completes the bio.h](hQFor decryption, blk-crypto-fallback “wraps” the bio’s completion callback (}(hjIhhhNhNubj )}(h``bi_complete``h]h bi_complete}(hjQhhhNhNubah}(h]h ]h"]h$]h&]uh1j hjIubh) and private data (}(hjIhhhNhNubj )}(h``bi_private``h]h bi_private}(hjchhhNhNubah}(h]h ]h"]h$]h&]uh1j hjIubhXx) with its own, unsets the bio’s encryption context, then submits the bio. If the read completes successfully, blk-crypto-fallback restores the bio’s original completion callback and private data, then decrypts the bio’s data in-place using the kernel crypto API. Decryption happens from a workqueue, as it may sleep. Afterwards, blk-crypto-fallback completes the bio.}(hjIhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hIn both cases, the bios that blk-crypto-fallback submits no longer have an encryption context. Therefore, lower layers only see standard unencrypted I/O.h]hIn both cases, the bios that blk-crypto-fallback submits no longer have an encryption context. Therefore, lower layers only see standard unencrypted I/O.}(hj{hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hXblk-crypto-fallback also defines its own blk_crypto_profile and has its own "keyslots"; its keyslots contain ``struct crypto_skcipher`` objects. The reason for this is twofold. First, it allows the keyslot management logic to be tested without actual inline encryption hardware. Second, similar to actual inline encryption hardware, the crypto API doesn't accept keys directly in requests but rather requires that keys be set ahead of time, and setting keys can be expensive; moreover, allocating a crypto_skcipher can't happen on the I/O path at all due to the locks it takes. Therefore, the concept of keyslots still makes sense for blk-crypto-fallback.h](hqblk-crypto-fallback also defines its own blk_crypto_profile and has its own “keyslots”; its keyslots contain }(hjhhhNhNubj )}(h``struct crypto_skcipher``h]hstruct crypto_skcipher}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j hjubhX objects. The reason for this is twofold. First, it allows the keyslot management logic to be tested without actual inline encryption hardware. Second, similar to actual inline encryption hardware, the crypto API doesn’t accept keys directly in requests but rather requires that keys be set ahead of time, and setting keys can be expensive; moreover, allocating a crypto_skcipher can’t happen on the I/O path at all due to the locks it takes. Therefore, the concept of keyslots still makes sense for blk-crypto-fallback.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hXiNote that regardless of whether real inline encryption hardware or blk-crypto-fallback is used, the ciphertext written to disk (and hence the on-disk format of data) will be the same (assuming that both the inline encryption hardware's implementation and the kernel crypto API's implementation of the algorithm being used adhere to spec and function correctly).h]hXmNote that regardless of whether real inline encryption hardware or blk-crypto-fallback is used, the ciphertext written to disk (and hence the on-disk format of data) will be the same (assuming that both the inline encryption hardware’s implementation and the kernel crypto API’s implementation of the algorithm being used adhere to spec and function correctly).}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hblk-crypto-fallback is optional and is controlled by the ``CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK`` kernel configuration option.h](h9blk-crypto-fallback is optional and is controlled by the }(hjhhhNhNubj )}(h)``CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK``h]h%CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j hjubh kernel configuration option.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubeh}(h]blk-crypto-fallbackah ]h"]blk-crypto-fallbackah$]h&]uh1hhhhhhhhKubh)}(hhh](h)}(h)API presented to users of the block layerh]h)API presented to users of the block layer}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhKubh)}(hX``blk_crypto_config_supported()`` allows users to check ahead of time whether inline encryption with particular crypto settings will work on a particular block_device -- either via hardware or via blk-crypto-fallback. This function takes in a ``struct blk_crypto_config`` which is like blk_crypto_key, but omits the actual bytes of the key and instead just contains the algorithm, data unit size, etc. This function can be useful if blk-crypto-fallback is disabled.h](j )}(h!``blk_crypto_config_supported()``h]hblk_crypto_config_supported()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j hjubh allows users to check ahead of time whether inline encryption with particular crypto settings will work on a particular block_device -- either via hardware or via blk-crypto-fallback. This function takes in a }(hjhhhNhNubj )}(h``struct blk_crypto_config``h]hstruct blk_crypto_config}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j hjubh which is like blk_crypto_key, but omits the actual bytes of the key and instead just contains the algorithm, data unit size, etc. This function can be useful if blk-crypto-fallback is disabled.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hF``blk_crypto_init_key()`` allows users to initialize a blk_crypto_key.h](j )}(h``blk_crypto_init_key()``h]hblk_crypto_init_key()}(hj"hhhNhNubah}(h]h ]h"]h$]h&]uh1j hjubh- allows users to initialize a blk_crypto_key.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hXqUsers must call ``blk_crypto_start_using_key()`` before actually starting to use a blk_crypto_key on a block_device (even if ``blk_crypto_config_supported()`` was called earlier). This is needed to initialize blk-crypto-fallback if it will be needed. This must not be called from the data path, as this may have to allocate resources, which may deadlock in that case.h](hUsers must call }(hj:hhhNhNubj )}(h ``blk_crypto_start_using_key()``h]hblk_crypto_start_using_key()}(hjBhhhNhNubah}(h]h ]h"]h$]h&]uh1j hj:ubhM before actually starting to use a blk_crypto_key on a block_device (even if }(hj:hhhNhNubj )}(h!``blk_crypto_config_supported()``h]hblk_crypto_config_supported()}(hjThhhNhNubah}(h]h ]h"]h$]h&]uh1j hj:ubh was called earlier). This is needed to initialize blk-crypto-fallback if it will be needed. This must not be called from the data path, as this may have to allocate resources, which may deadlock in that case.}(hj:hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hXtNext, to attach an encryption context to a bio, users should call ``bio_crypt_set_ctx()``. This function allocates a bio_crypt_ctx and attaches it to a bio, given the blk_crypto_key and the data unit number that will be used for en/decryption. Users don't need to worry about freeing the bio_crypt_ctx later, as that happens automatically when the bio is freed or reset.h](hBNext, to attach an encryption context to a bio, users should call }(hjlhhhNhNubj )}(h``bio_crypt_set_ctx()``h]hbio_crypt_set_ctx()}(hjthhhNhNubah}(h]h ]h"]h$]h&]uh1j hjlubhX. This function allocates a bio_crypt_ctx and attaches it to a bio, given the blk_crypto_key and the data unit number that will be used for en/decryption. Users don’t need to worry about freeing the bio_crypt_ctx later, as that happens automatically when the bio is freed or reset.}(hjlhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hXFinally, when done using inline encryption with a blk_crypto_key on a block_device, users must call ``blk_crypto_evict_key()``. This ensures that the key is evicted from all keyslots it may be programmed into and unlinked from any kernel data structures it may be linked into.h](hdFinally, when done using inline encryption with a blk_crypto_key on a block_device, users must call }(hjhhhNhNubj )}(h``blk_crypto_evict_key()``h]hblk_crypto_evict_key()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j hjubh. This ensures that the key is evicted from all keyslots it may be programmed into and unlinked from any kernel data structures it may be linked into.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hZIn summary, for users of the block layer, the lifecycle of a blk_crypto_key is as follows:h]hZIn summary, for users of the block layer, the lifecycle of a blk_crypto_key is as follows:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubhenumerated_list)}(hhh](jh)}(h,``blk_crypto_config_supported()`` (optional)h]h)}(hjh](j )}(h!``blk_crypto_config_supported()``h]hblk_crypto_config_supported()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j hjubh (optional)}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1jghjhhhhhNubjh)}(h``blk_crypto_init_key()``h]h)}(hjh]j )}(hjh]hblk_crypto_init_key()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j hjubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1jghjhhhhhNubjh)}(h ``blk_crypto_start_using_key()``h]h)}(hjh]j )}(hjh]hblk_crypto_start_using_key()}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j hjubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1jghjhhhhhNubjh)}(h0``bio_crypt_set_ctx()`` (potentially many times)h]h)}(hj&h](j )}(h``bio_crypt_set_ctx()``h]hbio_crypt_set_ctx()}(hj+hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj(ubh (potentially many times)}(hj(hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj$ubah}(h]h ]h"]h$]h&]uh1jghjhhhhhNubjh)}(h8``blk_crypto_evict_key()`` (after all I/O has completed)h]h)}(hjKh](j )}(h``blk_crypto_evict_key()``h]hblk_crypto_evict_key()}(hjPhhhNhNubah}(h]h ]h"]h$]h&]uh1j hjMubh (after all I/O has completed)}(hjMhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjIubah}(h]h ]h"]h$]h&]uh1jghjhhhhhNubjh)}(h | ----------------------------- | | Inline encryption key Software secreth]hX Hardware-wrapped key | | | ----------------------------- | | Inline encryption key Software secret}hj sbah}(h]h ]h"]h$]h&]hhuh1j hhhMhjh hhubh)}(hThe components are:h]hThe components are:}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjh hhubjc)}(hhh](jh)}(hX'*Hardware-wrapped key*: a key for the hardware's KDF (Key Derivation Function), in ephemerally-wrapped form. The key wrapping algorithm is a hardware implementation detail that doesn't impact kernel operation, but a strong authenticated encryption algorithm such as AES-256-GCM is recommended. h]h)}(hX&*Hardware-wrapped key*: a key for the hardware's KDF (Key Derivation Function), in ephemerally-wrapped form. The key wrapping algorithm is a hardware implementation detail that doesn't impact kernel operation, but a strong authenticated encryption algorithm such as AES-256-GCM is recommended.h](j")}(h*Hardware-wrapped key*h]hHardware-wrapped key}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j!hj ubhX: a key for the hardware’s KDF (Key Derivation Function), in ephemerally-wrapped form. The key wrapping algorithm is a hardware implementation detail that doesn’t impact kernel operation, but a strong authenticated encryption algorithm such as AES-256-GCM is recommended.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhj ubah}(h]h ]h"]h$]h&]uh1jghj hhhhhNubjh)}(hX*Hardware KDF*: a KDF (Key Derivation Function) which the hardware uses to derive subkeys after unwrapping the wrapped key. The hardware's choice of KDF doesn't impact kernel operation, but it does need to be known for testing purposes, and it's also assumed to have at least a 256-bit security strength. All known hardware uses the SP800-108 KDF in Counter Mode with AES-256-CMAC, with a particular choice of labels and contexts; new hardware should use this already-vetted KDF. h]h)}(hX*Hardware KDF*: a KDF (Key Derivation Function) which the hardware uses to derive subkeys after unwrapping the wrapped key. The hardware's choice of KDF doesn't impact kernel operation, but it does need to be known for testing purposes, and it's also assumed to have at least a 256-bit security strength. All known hardware uses the SP800-108 KDF in Counter Mode with AES-256-CMAC, with a particular choice of labels and contexts; new hardware should use this already-vetted KDF.h](j")}(h*Hardware KDF*h]h Hardware KDF}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j!hj ubhX: a KDF (Key Derivation Function) which the hardware uses to derive subkeys after unwrapping the wrapped key. The hardware’s choice of KDF doesn’t impact kernel operation, but it does need to be known for testing purposes, and it’s also assumed to have at least a 256-bit security strength. All known hardware uses the SP800-108 KDF in Counter Mode with AES-256-CMAC, with a particular choice of labels and contexts; new hardware should use this already-vetted KDF.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhj ubah}(h]h ]h"]h$]h&]uh1jghj hhhhhNubjh)}(hXx*Inline encryption key*: a derived key which the hardware directly provisions to a keyslot of the inline encryption hardware, without exposing it to software. In all known hardware, this will always be an AES-256-XTS key. However, in principle other encryption algorithms could be supported too. Hardware must derive distinct subkeys for each supported encryption algorithm. h]h)}(hXw*Inline encryption key*: a derived key which the hardware directly provisions to a keyslot of the inline encryption hardware, without exposing it to software. In all known hardware, this will always be an AES-256-XTS key. However, in principle other encryption algorithms could be supported too. Hardware must derive distinct subkeys for each supported encryption algorithm.h](j")}(h*Inline encryption key*h]hInline encryption key}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j!hj ubhX`: a derived key which the hardware directly provisions to a keyslot of the inline encryption hardware, without exposing it to software. In all known hardware, this will always be an AES-256-XTS key. However, in principle other encryption algorithms could be supported too. Hardware must derive distinct subkeys for each supported encryption algorithm.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhj ubah}(h]h ]h"]h$]h&]uh1jghj hhhhhNubjh)}(hX*Software secret*: a derived key which the hardware returns to software so that software can use it for cryptographic tasks that can't use inline encryption. This value is cryptographically isolated from the inline encryption key, i.e. knowing one doesn't reveal the other. (The KDF ensures this.) Currently, the software secret is always 32 bytes and thus is suitable for cryptographic applications that require up to a 256-bit security strength. Some use cases (e.g. full-disk encryption) won't require the software secret. h]h)}(hX*Software secret*: a derived key which the hardware returns to software so that software can use it for cryptographic tasks that can't use inline encryption. This value is cryptographically isolated from the inline encryption key, i.e. knowing one doesn't reveal the other. (The KDF ensures this.) Currently, the software secret is always 32 bytes and thus is suitable for cryptographic applications that require up to a 256-bit security strength. Some use cases (e.g. full-disk encryption) won't require the software secret.h](j")}(h*Software secret*h]hSoftware secret}(hj" hhhNhNubah}(h]h ]h"]h$]h&]uh1j!hj ubhX: a derived key which the hardware returns to software so that software can use it for cryptographic tasks that can’t use inline encryption. This value is cryptographically isolated from the inline encryption key, i.e. knowing one doesn’t reveal the other. (The KDF ensures this.) Currently, the software secret is always 32 bytes and thus is suitable for cryptographic applications that require up to a 256-bit security strength. Some use cases (e.g. full-disk encryption) won’t require the software secret.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhj ubah}(h]h ]h"]h$]h&]uh1jghj hhhhhNubeh}(h]h ]h"]h$]h&]jjuh1jbhhhMhjh hhubh)}(hXExample: in the case of fscrypt, the fscrypt master key (the key that protects a particular set of encrypted directories) is made hardware-wrapped. The inline encryption key is used as the file contents encryption key, while the software secret (rather than the master key directly) is used to key fscrypt's KDF (HKDF-SHA512) to derive other subkeys such as filenames encryption keys.h]hXExample: in the case of fscrypt, the fscrypt master key (the key that protects a particular set of encrypted directories) is made hardware-wrapped. The inline encryption key is used as the file contents encryption key, while the software secret (rather than the master key directly) is used to key fscrypt’s KDF (HKDF-SHA512) to derive other subkeys such as filenames encryption keys.}(hjF hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjh hhubh)}(hXoNote that currently this design assumes a single inline encryption key per hardware-wrapped key, without any further key derivation. Thus, in the case of fscrypt, currently hardware-wrapped keys are only compatible with the "inline encryption optimized" settings, which use one file contents encryption key per encryption policy rather than one per file. This design could be extended to make the hardware derive per-file keys using per-file nonces passed down the storage stack, and in fact some hardware already supports this; future work is planned to remove this limitation by adding the corresponding kernel support.h]hXsNote that currently this design assumes a single inline encryption key per hardware-wrapped key, without any further key derivation. Thus, in the case of fscrypt, currently hardware-wrapped keys are only compatible with the “inline encryption optimized” settings, which use one file contents encryption key per encryption policy rather than one per file. This design could be extended to make the hardware derive per-file keys using per-file nonces passed down the storage stack, and in fact some hardware already supports this; future work is planned to remove this limitation by adding the corresponding kernel support.}(hjT hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjh hhubeh}(h] key-hierarchyah ]h"] key hierarchyah$]h&]uh1hhjhhhhhMubh)}(hhh](h)}(hKernel supporth]hKernel support}(hjm hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjj hhhhhMubh)}(hThe inline encryption support of the kernel's block layer ("blk-crypto") has been extended to support hardware-wrapped keys as an alternative to raw keys, when hardware support is available. This works in the following way:h]hThe inline encryption support of the kernel’s block layer (“blk-crypto”) has been extended to support hardware-wrapped keys as an alternative to raw keys, when hardware support is available. This works in the following way:}(hj{ hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjj hhubjc)}(hhh](jh)}(hA ``key_types_supported`` field is added to the crypto capabilities in ``struct blk_crypto_profile``. This allows device drivers to declare that they support raw keys, hardware-wrapped keys, or both. h]h)}(hA ``key_types_supported`` field is added to the crypto capabilities in ``struct blk_crypto_profile``. This allows device drivers to declare that they support raw keys, hardware-wrapped keys, or both.h](hA }(hj hhhNhNubj )}(h``key_types_supported``h]hkey_types_supported}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj ubh. field is added to the crypto capabilities in }(hj hhhNhNubj )}(h``struct blk_crypto_profile``h]hstruct blk_crypto_profile}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj ubhd. This allows device drivers to declare that they support raw keys, hardware-wrapped keys, or both.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhj ubah}(h]h ]h"]h$]h&]uh1jghj hhhhhNubjh)}(hXI``struct blk_crypto_key`` can now contain a hardware-wrapped key as an alternative to a raw key; a ``key_type`` field is added to ``struct blk_crypto_config`` to distinguish between the different key types. This allows users of blk-crypto to en/decrypt data using a hardware-wrapped key in a way very similar to using a raw key. h]h)}(hXH``struct blk_crypto_key`` can now contain a hardware-wrapped key as an alternative to a raw key; a ``key_type`` field is added to ``struct blk_crypto_config`` to distinguish between the different key types. This allows users of blk-crypto to en/decrypt data using a hardware-wrapped key in a way very similar to using a raw key.h](j )}(h``struct blk_crypto_key``h]hstruct blk_crypto_key}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj ubhJ can now contain a hardware-wrapped key as an alternative to a raw key; a }(hj hhhNhNubj )}(h ``key_type``h]hkey_type}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj ubh field is added to }(hj hhhNhNubj )}(h``struct blk_crypto_config``h]hstruct blk_crypto_config}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj ubh to distinguish between the different key types. This allows users of blk-crypto to en/decrypt data using a hardware-wrapped key in a way very similar to using a raw key.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhj ubah}(h]h ]h"]h$]h&]uh1jghj hhhhhNubjh)}(hA new method ``blk_crypto_ll_ops::derive_sw_secret`` is added. Device drivers that support hardware-wrapped keys must implement this method. Users of blk-crypto can call ``blk_crypto_derive_sw_secret()`` to access this method. h]h)}(hA new method ``blk_crypto_ll_ops::derive_sw_secret`` is added. Device drivers that support hardware-wrapped keys must implement this method. Users of blk-crypto can call ``blk_crypto_derive_sw_secret()`` to access this method.h](h A new method }(hj hhhNhNubj )}(h'``blk_crypto_ll_ops::derive_sw_secret``h]h#blk_crypto_ll_ops::derive_sw_secret}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj ubhx is added. Device drivers that support hardware-wrapped keys must implement this method. Users of blk-crypto can call }(hj hhhNhNubj )}(h!``blk_crypto_derive_sw_secret()``h]hblk_crypto_derive_sw_secret()}(hj0 hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj ubh to access this method.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhj ubah}(h]h ]h"]h$]h&]uh1jghj hhhhhNubjh)}(hX)The programming and eviction of hardware-wrapped keys happens via ``blk_crypto_ll_ops::keyslot_program`` and ``blk_crypto_ll_ops::keyslot_evict``, just like it does for raw keys. If a driver supports hardware-wrapped keys, then it must handle hardware-wrapped keys being passed to these methods. h]h)}(hX(The programming and eviction of hardware-wrapped keys happens via ``blk_crypto_ll_ops::keyslot_program`` and ``blk_crypto_ll_ops::keyslot_evict``, just like it does for raw keys. If a driver supports hardware-wrapped keys, then it must handle hardware-wrapped keys being passed to these methods.h](hBThe programming and eviction of hardware-wrapped keys happens via }(hjR hhhNhNubj )}(h&``blk_crypto_ll_ops::keyslot_program``h]h"blk_crypto_ll_ops::keyslot_program}(hjZ hhhNhNubah}(h]h ]h"]h$]h&]uh1j hjR ubh and }(hjR hhhNhNubj )}(h$``blk_crypto_ll_ops::keyslot_evict``h]h blk_crypto_ll_ops::keyslot_evict}(hjl hhhNhNubah}(h]h ]h"]h$]h&]uh1j hjR ubh, just like it does for raw keys. If a driver supports hardware-wrapped keys, then it must handle hardware-wrapped keys being passed to these methods.}(hjR hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjN ubah}(h]h ]h"]h$]h&]uh1jghj hhhhhNubeh}(h]h ]h"]h$]h&]jjuh1jbhhhMhjj hhubh)}(hblk-crypto-fallback doesn't support hardware-wrapped keys. Therefore, hardware-wrapped keys can only be used with actual inline encryption hardware.h]hblk-crypto-fallback doesn’t support hardware-wrapped keys. Therefore, hardware-wrapped keys can only be used with actual inline encryption hardware.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjj hhubh)}(hAll the above deals with hardware-wrapped keys in ephemerally-wrapped form only. To get such keys in the first place, new block device ioctls have been added to provide a generic interface to creating and preparing such keys:h]hAll the above deals with hardware-wrapped keys in ephemerally-wrapped form only. To get such keys in the first place, new block device ioctls have been added to provide a generic interface to creating and preparing such keys:}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjj hhubjc)}(hhh](jh)}(hX``BLKCRYPTOIMPORTKEY`` converts a raw key to long-term wrapped form. It takes in a pointer to a ``struct blk_crypto_import_key_arg``. The caller must set ``raw_key_ptr`` and ``raw_key_size`` to the pointer and size (in bytes) of the raw key to import. On success, ``BLKCRYPTOIMPORTKEY`` returns 0 and writes the resulting long-term wrapped key blob to the buffer pointed to by ``lt_key_ptr``, which is of maximum size ``lt_key_size``. It also updates ``lt_key_size`` to be the actual size of the key. On failure, it returns -1 and sets errno. An errno of ``EOPNOTSUPP`` indicates that the block device does not support hardware-wrapped keys. An errno of ``EOVERFLOW`` indicates that the output buffer did not have enough space for the key blob. h]h)}(hX``BLKCRYPTOIMPORTKEY`` converts a raw key to long-term wrapped form. It takes in a pointer to a ``struct blk_crypto_import_key_arg``. The caller must set ``raw_key_ptr`` and ``raw_key_size`` to the pointer and size (in bytes) of the raw key to import. On success, ``BLKCRYPTOIMPORTKEY`` returns 0 and writes the resulting long-term wrapped key blob to the buffer pointed to by ``lt_key_ptr``, which is of maximum size ``lt_key_size``. It also updates ``lt_key_size`` to be the actual size of the key. On failure, it returns -1 and sets errno. An errno of ``EOPNOTSUPP`` indicates that the block device does not support hardware-wrapped keys. An errno of ``EOVERFLOW`` indicates that the output buffer did not have enough space for the key blob.h](j )}(h``BLKCRYPTOIMPORTKEY``h]hBLKCRYPTOIMPORTKEY}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj ubhK converts a raw key to long-term wrapped form. It takes in a pointer to a }(hj hhhNhNubj )}(h$``struct blk_crypto_import_key_arg``h]h struct blk_crypto_import_key_arg}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj ubh. The caller must set }(hj hhhNhNubj )}(h``raw_key_ptr``h]h raw_key_ptr}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj ubh and }(hj hhhNhNubj )}(h``raw_key_size``h]h raw_key_size}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj ubhK to the pointer and size (in bytes) of the raw key to import. On success, }(hj hhhNhNubj )}(h``BLKCRYPTOIMPORTKEY``h]hBLKCRYPTOIMPORTKEY}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj ubh[ returns 0 and writes the resulting long-term wrapped key blob to the buffer pointed to by }(hj hhhNhNubj )}(h``lt_key_ptr``h]h lt_key_ptr}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj ubh, which is of maximum size }(hj hhhNhNubj )}(h``lt_key_size``h]h lt_key_size}(hj# hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj ubh. It also updates }(hj hhhNhNubj )}(h``lt_key_size``h]h lt_key_size}(hj5 hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj ubh[ to be the actual size of the key. On failure, it returns -1 and sets errno. An errno of }(hj hhhNhNubj )}(h``EOPNOTSUPP``h]h EOPNOTSUPP}(hjG hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj ubhV indicates that the block device does not support hardware-wrapped keys. An errno of }(hj hhhNhNubj )}(h ``EOVERFLOW``h]h EOVERFLOW}(hjY hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj ubhM indicates that the output buffer did not have enough space for the key blob.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhj ubah}(h]h ]h"]h$]h&]uh1jghj hhhhhNubjh)}(h``BLKCRYPTOGENERATEKEY`` is like ``BLKCRYPTOIMPORTKEY``, but it has the hardware generate the key instead of importing one. It takes in a pointer to a ``struct blk_crypto_generate_key_arg``. h]h)}(h``BLKCRYPTOGENERATEKEY`` is like ``BLKCRYPTOIMPORTKEY``, but it has the hardware generate the key instead of importing one. It takes in a pointer to a ``struct blk_crypto_generate_key_arg``.h](j )}(h``BLKCRYPTOGENERATEKEY``h]hBLKCRYPTOGENERATEKEY}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj{ ubh is like }(hj{ hhhNhNubj )}(h``BLKCRYPTOIMPORTKEY``h]hBLKCRYPTOIMPORTKEY}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj{ ubha, but it has the hardware generate the key instead of importing one. It takes in a pointer to a }(hj{ hhhNhNubj )}(h&``struct blk_crypto_generate_key_arg``h]h"struct blk_crypto_generate_key_arg}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj{ ubh.}(hj{ hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjw ubah}(h]h ]h"]h$]h&]uh1jghj hhhhhNubjh)}(hX ``BLKCRYPTOPREPAREKEY`` converts a key from long-term wrapped form to ephemerally-wrapped form. It takes in a pointer to a ``struct blk_crypto_prepare_key_arg``. The caller must set ``lt_key_ptr`` and ``lt_key_size`` to the pointer and size (in bytes) of the long-term wrapped key blob to convert. On success, ``BLKCRYPTOPREPAREKEY`` returns 0 and writes the resulting ephemerally-wrapped key blob to the buffer pointed to by ``eph_key_ptr``, which is of maximum size ``eph_key_size``. It also updates ``eph_key_size`` to be the actual size of the key. On failure, it returns -1 and sets errno. Errno values of ``EOPNOTSUPP`` and ``EOVERFLOW`` mean the same as they do for ``BLKCRYPTOIMPORTKEY``. An errno of ``EBADMSG`` indicates that the long-term wrapped key is invalid. h]h)}(hX ``BLKCRYPTOPREPAREKEY`` converts a key from long-term wrapped form to ephemerally-wrapped form. It takes in a pointer to a ``struct blk_crypto_prepare_key_arg``. The caller must set ``lt_key_ptr`` and ``lt_key_size`` to the pointer and size (in bytes) of the long-term wrapped key blob to convert. On success, ``BLKCRYPTOPREPAREKEY`` returns 0 and writes the resulting ephemerally-wrapped key blob to the buffer pointed to by ``eph_key_ptr``, which is of maximum size ``eph_key_size``. It also updates ``eph_key_size`` to be the actual size of the key. On failure, it returns -1 and sets errno. Errno values of ``EOPNOTSUPP`` and ``EOVERFLOW`` mean the same as they do for ``BLKCRYPTOIMPORTKEY``. An errno of ``EBADMSG`` indicates that the long-term wrapped key is invalid.h](j )}(h``BLKCRYPTOPREPAREKEY``h]hBLKCRYPTOPREPAREKEY}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj ubhe converts a key from long-term wrapped form to ephemerally-wrapped form. It takes in a pointer to a }(hj hhhNhNubj )}(h%``struct blk_crypto_prepare_key_arg``h]h!struct blk_crypto_prepare_key_arg}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj ubh. The caller must set }(hj hhhNhNubj )}(h``lt_key_ptr``h]h lt_key_ptr}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj ubh and }(hj hhhNhNubj )}(h``lt_key_size``h]h lt_key_size}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj ubh_ to the pointer and size (in bytes) of the long-term wrapped key blob to convert. On success, }(hj hhhNhNubj )}(h``BLKCRYPTOPREPAREKEY``h]hBLKCRYPTOPREPAREKEY}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj ubh] returns 0 and writes the resulting ephemerally-wrapped key blob to the buffer pointed to by }(hj hhhNhNubj )}(h``eph_key_ptr``h]h eph_key_ptr}(hj# hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj ubh, which is of maximum size }(hj hhhNhNubj )}(h``eph_key_size``h]h eph_key_size}(hj5 hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj ubh. It also updates }(hj hhhNhNubj )}(h``eph_key_size``h]h eph_key_size}(hjG hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj ubh_ to be the actual size of the key. On failure, it returns -1 and sets errno. Errno values of }(hj hhhNhNubj )}(h``EOPNOTSUPP``h]h EOPNOTSUPP}(hjY hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj ubh and }(hj hhhNhNubj )}(h ``EOVERFLOW``h]h EOVERFLOW}(hjk hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj ubh mean the same as they do for }(hj hhhNhNubj )}(h``BLKCRYPTOIMPORTKEY``h]hBLKCRYPTOIMPORTKEY}(hj} hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj ubh. An errno of }(hj hhhNhNubj )}(h ``EBADMSG``h]hEBADMSG}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj ubh5 indicates that the long-term wrapped key is invalid.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhj ubah}(h]h ]h"]h$]h&]uh1jghj hhhhhNubeh}(h]h ]h"]h$]h&]jjuh1jbhhhMhjj hhubh)}(hXUserspace needs to use either ``BLKCRYPTOIMPORTKEY`` or ``BLKCRYPTOGENERATEKEY`` once to create a key, and then ``BLKCRYPTOPREPAREKEY`` each time the key is unlocked and added to the kernel. Note that these ioctls have no relevance for raw keys; they are only for hardware-wrapped keys.h](hUserspace needs to use either }(hj hhhNhNubj )}(h``BLKCRYPTOIMPORTKEY``h]hBLKCRYPTOIMPORTKEY}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj ubh or }(hj hhhNhNubj )}(h``BLKCRYPTOGENERATEKEY``h]hBLKCRYPTOGENERATEKEY}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj ubh once to create a key, and then }(hj hhhNhNubj )}(h``BLKCRYPTOPREPAREKEY``h]hBLKCRYPTOPREPAREKEY}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj ubh each time the key is unlocked and added to the kernel. Note that these ioctls have no relevance for raw keys; they are only for hardware-wrapped keys.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjj hhubeh}(h]kernel-supportah ]h"]kernel supportah$]h&]uh1hhjhhhhhMubh)}(hhh](h)}(h Testabilityh]h Testability}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hhhhhMubh)}(hXSBoth the hardware KDF and the inline encryption itself are well-defined algorithms that don't depend on any secrets other than the unwrapped key. Therefore, if the unwrapped key is known to software, these algorithms can be reproduced in software in order to verify the ciphertext that is written to disk by the inline encryption hardware.h]hXUBoth the hardware KDF and the inline encryption itself are well-defined algorithms that don’t depend on any secrets other than the unwrapped key. Therefore, if the unwrapped key is known to software, these algorithms can be reproduced in software in order to verify the ciphertext that is written to disk by the inline encryption hardware.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj hhubh)}(hXHowever, the unwrapped key will only be known to software for testing if the "import" functionality is used. Proper testing is not possible in the "generate" case where the hardware generates the key itself. The correct operation of the "generate" mode thus relies on the security and correctness of the hardware RNG and its use to generate the key, as well as the testing of the "import" mode as that should cover all parts other than the key generation.h]hXHowever, the unwrapped key will only be known to software for testing if the “import” functionality is used. Proper testing is not possible in the “generate” case where the hardware generates the key itself. The correct operation of the “generate” mode thus relies on the security and correctness of the hardware RNG and its use to generate the key, as well as the testing of the “import” mode as that should cover all parts other than the key generation.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj hhubh)}(hX"For an example of a test that verifies the ciphertext written to disk in the "import" mode, see the fscrypt hardware-wrapped key tests in xfstests, or `Android's vts_kernel_encryption_test `_.h](hFor an example of a test that verifies the ciphertext written to disk in the “import” mode, see the fscrypt hardware-wrapped key tests in xfstests, or }(hj,hhhNhNubh reference)}(h`Android's vts_kernel_encryption_test `_h]h&Android’s vts_kernel_encryption_test}(hj6hhhNhNubah}(h]h ]h"]h$]h&]name$Android's vts_kernel_encryption_testrefuri`https://android.googlesource.com/platform/test/vts-testcase/kernel/+/refs/heads/main/encryption/uh1j4hj,ubh)}(hc h]h}(h]$android-s-vts-kernel-encryption-testah ]h"]$android's vts_kernel_encryption_testah$]h&]refurijGuh1h referencedKhj,ubh.}(hj,hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM#hj hhubeh}(h] testabilityah ]h"] testabilityah$]h&]uh1hhjhhhhhMubeh}(h](jid2eh ]h"](hardware-wrapped keyshardware_wrapped_keyseh$]h&]uh1hhhhhhhhM4expect_referenced_by_name}jnjsexpect_referenced_by_id}jjsubeh}(h](hid1eh ]h"](inline encryptioninline_encryptioneh$]h&]uh1hhhhhhhhKjq}j{hsjs}hhsubeh}(h]h ]h"]h$]h&]sourcehuh1hcurrent_sourceN current_lineNsettingsdocutils.frontendValues)}(hN generatorN datestampN source_linkN source_urlN toc_backlinksentryfootnote_backlinksK sectnum_xformKstrip_commentsNstrip_elements_with_classesN strip_classesN report_levelK halt_levelKexit_status_levelKdebugNwarning_streamN tracebackinput_encoding utf-8-siginput_encoding_error_handlerstrictoutput_encodingutf-8output_encoding_error_handlerjerror_encodingutf-8error_encoding_error_handlerbackslashreplace language_codeenrecord_dependenciesNconfigN id_prefixhauto_id_prefixid dump_settingsNdump_internalsNdump_transformsNdump_pseudo_xmlNexpose_internalsNstrict_visitorN_disable_configN_sourceh _destinationN _config_files]7/var/lib/git/docbuild/linux/Documentation/docutils.confafile_insertion_enabled raw_enabledKline_length_limitM'pep_referencesN pep_base_urlhttps://peps.python.org/pep_file_url_templatepep-%04drfc_referencesN rfc_base_url&https://datatracker.ietf.org/doc/html/ tab_widthKtrim_footnote_reference_spacesyntax_highlightlong smart_quotessmartquotes_locales]character_level_inline_markupdoctitle_xform docinfo_xformKsectsubtitle_xform image_loadinglinkembed_stylesheetcloak_email_addressessection_self_linkenvNubreporterNindirect_targets]substitution_defs}substitution_names}refnames}refids}(h]haj]jaunameids}(j{hjzjwj'j$jNjKjjjjjjjjjQjNjxjujjjnjjmjjjjje jb jg jd j j jejbjQjNu nametypes}(j{jzj'jNjjjjjQjxjjnjmjje jg j jejQuh}(hhjwhj$hjKj*jjQjjjjjjjNjjujTjj{jjjjjjjjb jjd jh j jj jbj jNjHu footnote_refs} citation_refs} autofootnotes]autofootnote_refs]symbol_footnotes]symbol_footnote_refs] footnotes] citations]autofootnote_startKsymbol_footnote_startK id_counter collectionsCounter}jKsRparse_messages]transform_messages](hsystem_message)}(hhh]h)}(hhh]h7Hyperlink target "inline-encryption" is not referenced.}hjsbah}(h]h ]h"]h$]h&]uh1hhj ubah}(h]h ]h"]h$]h&]levelKtypeINFOsourcehlineKuh1j ubj )}(hhh]h)}(hhh]h;Hyperlink target "hardware-wrapped-keys" is not referenced.}hj)sbah}(h]h ]h"]h$]h&]uh1hhj&ubah}(h]h ]h"]h$]h&]levelKtypej#sourcehlineM1uh1j ube transformerN include_log] decorationNhhub.