요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
성능·integrity option
dm-crypt.rst:93-188Discard 보안, CPU/workqueue, AEAD metadata, sector-size IV와 request split 설정을 설명합니다.
dmsetup과 LUKS
dm-crypt.rst:189-212Hex key, keyring key를 사용한 dmsetup table과 권장 cryptsetup LUKS 절차를 제공합니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
========
dm-crypt
========
Device-Mapper's "crypt" target provides transparent encryption of block devices
using the kernel crypto API.
For a more detailed description of supported parameters see:
https://gitlab.com/cryptsetup/cryptsetup/wikis/DMCrypt
Parameters::
<cipher> <key> <iv_offset> <device path> \
<offset> [<#opt_params> <opt_params>]
<cipher>
Encryption cipher, encryption mode and Initial Vector (IV) generator.
The cipher specifications format is::
cipher[:keycount]-chainmode-ivmode[:ivopts]
Examples::
aes-cbc-essiv:sha256
aes-xts-plain64
serpent-xts-plain64
Cipher format also supports direct specification with kernel crypt API
format (selected by capi: prefix). The IV specification is the same
as for the first format type.
This format is mainly used for specification of authenticated modes.
The crypto API cipher specifications format is::
capi:cipher_api_spec-ivmode[:ivopts]
Examples::
capi:cbc(aes)-essiv:sha256
capi:xts(aes)-plain64
Examples of authenticated modes::
capi:gcm(aes)-random
capi:authenc(hmac(sha256),xts(aes))-random
capi:rfc7539(chacha20,poly1305)-random
The /proc/crypto contains a list of currently loaded crypto modes.
<key>
Key used for encryption. It is encoded either as a hexadecimal number
or it can be passed as <key_string> prefixed with single colon
character (':') for keys residing in kernel keyring service.
You can only use key sizes that are valid for the selected cipher
in combination with the selected iv mode.
Note that for some iv modes the key string can contain additional
keys (for example IV seed) so the key contains more parts concatenated
into a single string.
<key_string>
The kernel keyring key is identified by string in following format:
<key_size>:<key_type>:<key_description>.
<key_size>
The encryption key size in bytes. The kernel key payload size must match
the value passed in <key_size>.
<key_type>
Either 'logon', 'user', 'encrypted' or 'trusted' kernel key type.
<key_description>
The kernel keyring key description crypt target should look for
when loading key of <key_type>.
<keycount>
Multi-key compatibility mode. You can define <keycount> keys and
then sectors are encrypted according to their offsets (sector 0 uses key0;
sector 1 uses key1 etc.). <keycount> must be a power of two.
<iv_offset>
The IV offset is a sector count that is added to the sector number
before creating the IV.
<device path>
This is the device that is going to be used as backend and contains the
encrypted data. You can specify it as a path like /dev/xxx or a device
number <major>:<minor>.
<offset>
Starting sector within the device where the encrypted data begins.
<#opt_params>
Number of optional parameters. If there are no optional parameters,
the optional parameters section can be skipped or #opt_params can be zero.
Otherwise #opt_params is the number of following arguments.
Example of optional parameters section:
3 allow_discards same_cpu_crypt submit_from_crypt_cpus
allow_discards
Block discard requests (a.k.a. TRIM) are passed through the crypt device.
The default is to ignore discard requests.
WARNING: Assess the specific security risks carefully before enabling this
option. For example, allowing discards on encrypted devices may lead to
the leak of information about the ciphertext device (filesystem type,
used space etc.) if the discarded blocks can be located easily on the
device later.
same_cpu_crypt
Perform encryption using the same cpu that IO was submitted on.
The default is to use an unbound workqueue so that encryption work
is automatically balanced between available CPUs.
high_priority
Set dm-crypt workqueues and the writer thread to high priority. This
improves throughput and latency of dm-crypt while degrading general
responsiveness of the system.
submit_from_crypt_cpus
Disable offloading writes to a separate thread after encryption.
There are some situations where offloading write bios from the
encryption threads to a single thread degrades performance
significantly. The default is to offload write bios to the same
thread because it benefits CFQ to have writes submitted using the
same context.
no_read_workqueue
Bypass dm-crypt internal workqueue and process read requests synchronously.
no_write_workqueue
Bypass dm-crypt internal workqueue and process write requests synchronously.
This option is automatically enabled for host-managed zoned block devices
(e.g. host-managed SMR hard-disks).
integrity:<bytes>:<type>
The device requires additional <bytes> metadata per-sector stored
in per-bio integrity structure. This metadata must by provided
by underlying dm-integrity target.
The <type> can be "none" if metadata is used only for persistent IV.
For Authenticated Encryption with Additional Data (AEAD)
the <type> is "aead". An AEAD mode additionally calculates and verifies
integrity for the encrypted device. The additional space is then
used for storing authentication tag (and persistent IV if needed).
integrity_key_size:<bytes>
Optionally set the integrity key size if it differs from the digest size.
It allows the use of wrapped key algorithms where the key size is
independent of the cryptographic key size.
sector_size:<bytes>
Use <bytes> as the encryption unit instead of 512 bytes sectors.
This option can be in range 512 - 4096 bytes and must be power of two.
Virtual device will announce this size as a minimal IO and logical sector.
iv_large_sectors
IV generators will use sector number counted in <sector_size> units
instead of default 512 bytes sectors.
For example, if <sector_size> is 4096 bytes, plain64 IV for the second
sector will be 8 (without flag) and 1 if iv_large_sectors is present.
The <iv_offset> must be multiple of <sector_size> (in 512 bytes units)
if this flag is specified.
integrity_key_size:<bytes>
Use an integrity key of <bytes> size instead of using an integrity key size
of the digest size of the used HMAC algorithm.
Module parameters::
max_read_size
Maximum size of read requests. When a request larger than this size
is received, dm-crypt will split the request. The splitting improves
concurrency (the split requests could be encrypted in parallel by multiple
cores), but it also causes overhead. The user should tune this parameters to
fit the actual workload.
max_write_size
Maximum size of write requests. When a request larger than this size
is received, dm-crypt will split the request. The splitting improves
concurrency (the split requests could be encrypted in parallel by multiple
cores), but it also causes overhead. The user should tune this parameters to
fit the actual workload.
Example scripts
===============
LUKS (Linux Unified Key Setup) is now the preferred way to set up disk
encryption with dm-crypt using the 'cryptsetup' utility, see
https://gitlab.com/cryptsetup/cryptsetup
::
#!/bin/sh
# Create a crypt device using dmsetup
dmsetup create crypt1 --table "0 `blockdev --getsz $1` crypt aes-cbc-essiv:sha256 babebabebabebabebabebabebabebabe 0 $1 0"
::
#!/bin/sh
# Create a crypt device using dmsetup when encryption key is stored in keyring service
dmsetup create crypt2 --table "0 `blockdev --getsize $1` crypt aes-cbc-essiv:sha256 :32:logon:my_prefix:my_key 0 $1 0"
::
#!/bin/sh
# Create a crypt device using cryptsetup and LUKS header with default cipher
cryptsetup luksFormat $1
cryptsetup luksOpen $1 crypt1
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
Transparent block-device encryption
1-15Device-Mapper의 `crypt` target은 kernel crypto API를 사용해 block device를 투명하게 암호화합니다.
지원 parameter의 더 자세한 설명은 `https://gitlab.com/cryptsetup/cryptsetup/wikis/DMCrypt`에서 볼 수 있습니다.
Target parameter의 기본 형식은 다음과 같습니다.
<cipher> <key> <iv_offset> <device path> \
<offset> [<#opt_params> <opt_params>]
Virtual crypt device가 block I/O와 backend의 encrypted data 사이에서 변환합니다.
Cipher와 IV generator 형식
16-50`<cipher>`는 encryption cipher, encryption mode와 Initial Vector(IV) generator를 지정합니다. 일반 cipher specification 형식은 다음과 같습니다.
cipher[:keycount]-chainmode-ivmode[:ivopts]
일반 형식의 예는 다음과 같습니다.
aes-cbc-essiv:sha256
aes-xts-plain64
serpent-xts-plain64
`capi:` prefix를 사용하면 kernel crypt API 형식으로 cipher를 직접 지정할 수도 있습니다. IV specification은 첫 형식과 같고, 이 형식은 주로 authenticated mode를 지정할 때 사용합니다.
capi:cipher_api_spec-ivmode[:ivopts]
Crypto API cipher specification의 예는 다음과 같습니다.
capi:cbc(aes)-essiv:sha256
capi:xts(aes)-plain64
Authenticated mode의 예는 다음과 같습니다.
capi:gcm(aes)-random
capi:authenc(hmac(sha256),xts(aes))-random
capi:rfc7539(chacha20,poly1305)-random
현재 load된 crypto mode 목록은 `/proc/crypto`에서 확인할 수 있습니다.
일반 dm-crypt 이름과 kernel crypto API 직접 지정 방식을 비교합니다.
Cipher, authenticator와 IV mode 조합을 그대로 지정합니다.
Keyring key와 multi-key mode
51-92`<key>`는 encryption에 사용할 key입니다. Hexadecimal number로 encode하거나, kernel keyring service에 있는 key는 single colon(`:`)을 앞에 붙인 `<key_string>`으로 전달합니다.
선택한 cipher와 IV mode 조합에 유효한 key size만 사용할 수 있습니다. 일부 IV mode에서는 key string에 IV seed 같은 추가 key가 들어가 여러 부분을 하나의 문자열로 연결할 수 있습니다.
Kernel keyring key는 `<key_size>:<key_type>:<key_description>` 형식의 문자열로 식별합니다.
Key payload와 lookup 정보를 한 문자열로 지정합니다.
`<keycount>`는 multi-key compatibility mode입니다. 지정한 수만큼 key를 정의하고 sector offset에 따라 key를 순환해 사용합니다. Sector 0은 key0, sector 1은 key1을 사용합니다. `keycount`는 2의 거듭제곱이어야 합니다.
`<iv_offset>`은 IV를 만들기 전에 sector number에 더하는 sector count입니다. `<device path>`는 encrypted data를 보관할 backend로 `/dev/xxx` path 또는 `<major>:<minor>` device number를 쓸 수 있습니다. `<offset>`은 encrypted data가 시작되는 device 내부 sector입니다.
Sector offset에 따라 key를 순환 선택하며 keycount는 power of two입니다.
Optional performance와 discard parameter
93-136`<#opt_params>`는 optional parameter 수입니다. Parameter가 없으면 이 구간을 생략하거나 0으로 지정합니다. 그 외에는 뒤따르는 argument 수를 적습니다.
Optional parameter 구간의 예는 다음과 같습니다.
3 allow_discards same_cpu_crypt submit_from_crypt_cpus
Discard 전달과 crypto/write execution context를 조정합니다.
`allow_discards`를 활성화하기 전에 구체적인 보안 위험을 신중히 평가해야 합니다. Encrypted device에서 discard를 허용하면 나중에 discarded block 위치를 쉽게 알아낼 수 있을 때 filesystem type, used space 같은 ciphertext device 정보가 누출될 수 있습니다.
기본적으로 write bio는 encryption thread에서 같은 context의 단일 thread로 offload합니다. 이는 동일 context에서 write를 submit하는 것이 CFQ에 유리하기 때문입니다. 하지만 일부 상황에서는 단일 thread로 offload하는 동작이 성능을 크게 떨어뜨려 `submit_from_crypt_cpus`가 유용합니다.
`no_write_workqueue`는 host-managed SMR hard disk 같은 host-managed zoned block device에서 자동으로 활성화됩니다.
TRIM 전달은 storage 효율을 높이지만 encrypted layout 정보를 드러낼 수 있습니다.
Integrity metadata와 encryption sector
137-171`integrity:<bytes>:<type>`은 device가 sector마다 추가 `<bytes>` metadata를 per-bio integrity structure에 요구함을 나타냅니다. 이 metadata는 아래의 dm-integrity target이 제공해야 합니다.
Metadata를 persistent IV 용도로만 사용하면 `<type>`을 `none`으로 지정할 수 있습니다. Authenticated Encryption with Additional Data(AEAD)에서는 `<type>`이 `aead`입니다. AEAD mode는 encrypted device의 integrity도 계산·검증하고 추가 공간에 authentication tag와 필요하면 persistent IV를 저장합니다.
`integrity_key_size:<bytes>`로 integrity key 크기가 digest size와 다를 때 값을 지정할 수 있습니다. Cryptographic key size와 독립된 key size를 갖는 wrapped key algorithm을 사용할 수 있게 합니다. 아래에서 이 option은 사용한 HMAC algorithm의 digest size 대신 지정 byte 크기의 integrity key를 쓴다는 의미로 다시 설명됩니다.
`sector_size:<bytes>`는 기본 512-byte sector 대신 지정 byte를 encryption unit으로 사용합니다. 범위는 512-4096 byte이고 2의 거듭제곱이어야 합니다. Virtual device는 이 값을 minimal I/O와 logical sector size로 알립니다.
`iv_large_sectors`를 지정하면 IV generator가 기본 512-byte sector가 아니라 `<sector_size>` 단위로 센 sector number를 사용합니다. 예를 들어 `sector_size`가 4096 byte이면 두 번째 sector의 plain64 IV는 flag가 없을 때 8이고 `iv_large_sectors`가 있으면 1입니다.
`iv_large_sectors`를 사용할 때 `<iv_offset>`은 512-byte 단위로 표현한 `<sector_size>`의 배수여야 합니다.
Per-sector metadata, key 크기와 encryption unit을 지정합니다.
두 번째 4096-byte sector는 512-byte 단위로는 index 8, large-sector 단위로는 index 1입니다.
Read/write request split 크기
172-188큰 request를 나눠 여러 core에서 병렬 encryption할 수 있습니다.
dmsetup, keyring과 LUKS 예제
189-212현재 dm-crypt disk encryption 설정에는 `cryptsetup` utility와 LUKS(Linux Unified Key Setup)를 사용하는 방법이 권장됩니다. 자세한 내용은 `https://gitlab.com/cryptsetup/cryptsetup`을 참고합니다.
첫 script는 hexadecimal key와 `aes-cbc-essiv:sha256`을 사용해 dmsetup으로 `crypt1` device를 만듭니다.
#!/bin/sh
# Create a crypt device using dmsetup
dmsetup create crypt1 --table "0 `blockdev --getsz $1` crypt aes-cbc-essiv:sha256 babebabebabebabebabebabebabebabe 0 $1 0"
두 번째 script는 kernel keyring service에 저장된 32-byte `logon` key `my_prefix:my_key`를 사용해 `crypt2` device를 만듭니다.
#!/bin/sh
# Create a crypt device using dmsetup when encryption key is stored in keyring service
dmsetup create crypt2 --table "0 `blockdev --getsize $1` crypt aes-cbc-essiv:sha256 :32:logon:my_prefix:my_key 0 $1 0"
세 번째 script는 cryptsetup으로 기본 cipher를 사용하는 LUKS header를 만들고 이를 `crypt1` 이름으로 엽니다.
#!/bin/sh
# Create a crypt device using cryptsetup and LUKS header with default cipher
cryptsetup luksFormat $1
cryptsetup luksOpen $1 crypt1
직접 dmsetup table을 구성할 수도 있지만 일반 disk encryption은 cryptsetup과 LUKS를 사용합니다.
Cipher와 key 형식
dm-crypt.rst:1-92Target parameter, 일반·Crypto API cipher specification, IV와 kernel keyring key 형식을 정리합니다.