NetBSD-10で追加されたSWAP領域暗号化機能

[NetBSD Advent Calendar 2024](https://qiita.com/advent-calendar/2024/netbsd) 4日目の記事です。今日はNetBSD-10でSWAP領域に追加された機能を紹介しようと思います。

## SWAP領域の暗号化がデフォルトで有効化された

NetBSD-10における、(NetBSD-9.3からの)[追加・変更箇所](https://www.netbsd.org/releases/formal-10/NetBSD-10.0.html)を見ると以下のような記述がありました。

> Swap encryption is now automatic using the vm.swap_encrypt=1 sysctl(8) variable.

どうやらSWAP領域の暗号化がデフォルトで有効化されたようです。[sysctl(8)](https://man.netbsd.org/NetBSD-10.0/sysctl.8)に `vm.swap_encrypt` というMIB(Management Information Base)エントリが追加されています。

```sh
$ sysctl -d vm.swap_encrypt
vm.swap_encrypt: Encrypt data when swapped out to disk
$
$ sysctl vm.swap_encrypt
vm.swap_encrypt = 1
```

[swapctl(8)](https://man.netbsd.org/NetBSD-10.0/swapctl.8)からは暗号化が有効・無効なのかは確認できないようですね。
(OSの機能なのでカーネル内で保持している値を確認できる `sysctl` コマンドを使用してくださいという話なのかと思います)

```sh
swapctl -l
Device      1K-blocks     Used    Avail Capacity  Priority
/dev/dk1      1048576        0  1048576     0%    0
```

## カーネルコードを見てみる

SWAP領域の暗号化に関連するカーネルコードを眺めてみます。[/usr/src/sys/uvm/uvm_swap.c](https://github.com/NetBSD/src/blob/trunk/sys/uvm/uvm_swap.c)で必要な機能が実装されています。

`sysctl` で確認できる `vm.swap_encrypt` は以下の個所で定義されています。MIBエントリの追加手順は過去の記事で紹介しており、これを参考にコードを読んでみます。

 * [NetBSDカーネルのsysctl処理を追いかけてみた]()(2014/12/15)

```c
2148 SYSCTL_SETUP(sysctl_uvmswap_setup, "sysctl uvmswap setup")
2149 {
2150
2151     sysctl_createv(clog, 0, NULL, NULL,
2152         CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_BOOL, "swap_encrypt",
2153         SYSCTL_DESCR("Encrypt data when swapped out to disk"),
2154         NULL, 0, &uvm_swap_encrypt, 0,
2155         CTL_VM, CTL_CREATE, CTL_EOL);
2156 }
```

[sysctl_createv(9)](https://man.netbsd.org/NetBSD-10.0/sysctl_createv.9)の第11引数に指定している `&uvm_swap_encrypt` で暗号化の有無を設定するようです。 `&uvm_swap_encrypt` は `bool` 型の変数で、さらに `VMSWAP_DEFAULT_PLAINTEXT` というマクロで条件コンパイルされています。

```c
 214 #if VMSWAP_DEFAULT_PLAINTEXT
 215 bool uvm_swap_encrypt = false;
 216 #else
 217 bool uvm_swap_encrypt = true;
 218 #endif
```

## アーキテクチャ毎のSWAP領域暗号化

`VMSWAP_DEFAULT_PLAINTEXT` について調べてみましょう。いくつかのアーキテクチャにおいて、カーネルコンフィグ中で設定されているようです。どうやら全てのアーキテクチャでSWAP領域の暗号化が有効になるわけではなさそうです。

```sh
$ find /usr/src/sys/arch/ -type f \
    | grep conf/std \
    | xargs grep VMSWAP_DEFAULT_PLAINTEXT
/usr/src/sys/arch/alpha/conf/std.alpha:options          VMSWAP_DEFAULT_PLAINTEXT
/usr/src/sys/arch/cobalt/conf/std.cobalt:options                VMSWAP_DEFAULT_PLAINTEXT        # do not encrypt swap by
/usr/src/sys/arch/evbppc/conf/std.explora:options       VMSWAP_DEFAULT_PLAINTEXT        # do not encrypt swap by
/usr/src/sys/arch/hpcarm/conf/std.hpcarm:options        VMSWAP_DEFAULT_PLAINTEXT        # do not encrypt swap by
/usr/src/sys/arch/hpcmips/conf/std.hpcmips:options      VMSWAP_DEFAULT_PLAINTEXT        # do not encrypt swap by
/usr/src/sys/arch/m68k/conf/std.m68k:options            VMSWAP_DEFAULT_PLAINTEXT        # do not encrypt swap by
/usr/src/sys/arch/playstation2/conf/std.playstation2:options            VMSWAP_DEFAULT_PLAINTEXT        # do not encrypt swap by
/usr/src/sys/arch/pmax/conf/std.pmax:options            VMSWAP_DEFAULT_PLAINTEXT        # do not encrypt swap by
/usr/src/sys/arch/pmax/conf/std.pmax64:options          VMSWAP_DEFAULT_PLAINTEXT        # do not encrypt swap by
/usr/src/sys/arch/sh3/conf/std.sh3:options              VMSWAP_DEFAULT_PLAINTEXT        # do not encrypt swap by
/usr/src/sys/arch/shark/conf/std.ofwgencfg:options              VMSWAP_DEFAULT_PLAINTEXT        # do not encrypt swap by
/usr/src/sys/arch/shark/conf/std.shark:options          VMSWAP_DEFAULT_PLAINTEXT        # do not encrypt swap by
/usr/src/sys/arch/sparc/conf/std.sparc:options          VMSWAP_DEFAULT_PLAINTEXT        # do not encrypt swap by
/usr/src/sys/arch/vax/conf/std.vax:options              VMSWAP_DEFAULT_PLAINTEXT        # do not encrypt swap by
```

[NetBSD/hpcmips](http://www.jp.netbsd.org/ja/ports/hpcmips/)(MIPSベースのWindowsCEマシン)や[NetBSD/sh3](https://wiki.netbsd.org/ports/sh3/)([SuperH](https://ja.wikipedia.org/wiki/SuperH)シリーズへのNetBSDポート)などで `VMSWAP_DEFAULT_PLAINTEXT` が設定されており、何となく理由が推測できますね…。実際にコンフィグファイルを確認すると、"do not encrypt swap by default (slow cpu)"と理由が書かれていました。

```sh
cat /usr/src/sys/arch/sh3/conf/std.sh3
# $NetBSD: std.sh3,v 1.7 2021/06/04 10:46:11 martin Exp $
#
# standard, required NetBSD/sh3 'options'

options         EXEC_ELF32      # exec ELF binaries
options         EXEC_SCRIPT     # exec #! scripts

options         CPU_IN_CKSUM    # use assembler version of cpu_in_cksum()

options         VMSWAP_DEFAULT_PLAINTEXT        # do not encrypt swap by
                                # default (slow cpu)
```

## まとめ

NetBSD-10で有効化されたSWAP領域の暗号化機能について紹介しました。デフォルトで有効になっているとはいえ、一部のアーキテクチャではCPUの計算能力の観点から暗号化が無効化されていました。