デュアルブート環境で Bluetooth を使いたい!

問題

Windows と Linux のどちらか片方でしかペアリングができない。 これは,Windows と Linux でデュアルブートする際, Bluetooth のインターフェースを共有することに起因する。 Bluetooth のペアリングは,ある MAC アドレスの Bluetooth インターフェースに対して Bluetooth 周辺機器がペアリングすることになるため,片方の OS でペアリングしてしまうと,もう片方の OS ではまだペアリングしていないのに周辺機器は「ペアリング済」と判断してしまう,ということである。 周辺機器側でペアリング登録の解除が可能ならば(たとえば iPhone はペアリング済みのホストを一覧・解除できる)両方の OS でペアリング動作は行えるものの,両方の OS でペアリングに使うキーが異なってしまう。しかし,周辺機器が特定の MAC アドレスの Bluetooth インターフェースに対して記憶するペアリングキーは当然ひとつだけである。

解決方法

Linux ならテキストファイル,Windows ならレジストリにペアリングキーが書き込まれる。片方の OS でこれを閲覧して,もう片方の OS のペアリングキーを上書きしてしまえば良い。

手順

まず,Linux でペアリングする。次に,Windows でペアリングしなおす。この時点で Linux で接続が失敗するようになる。

ここからがミソである。Linux を起動し,chntpw をインストールする。これは,Windows のレジストリファイルを編集することが可能なコマンドである。

たとえば,Windows の C ドライブにあたるパーティションを /media にマウントしていた場合,

$ chntpw -e /media/Windows/System32/config/SYSTEM
chntpw version 1.00 140201, (c) Petter N Hagen
Hive </media/Windows/System32/config/SYSTEM> name (from header): <SYSTEM>
ROOT KEY at offset: 0x001020 * Subkey indexing type is: 686c <lh>
File size 23855104 [16c0000] bytes, containing 5166 pages (+ 1 headerpage)
Used for data: 368592/23358472 blocks/bytes, unused: 17/28216 blocks/bytes.

Simple registry editor. ? for help.

> cd ControlSet001\Services\BTHPORT\Parameters\Keys

(...)\Services\BTHPORT\Parameters\Keys> ls
Node has 1 subkeys and 0 values
  key name
  <deadbeef0000>

(...)\Services\BTHPORT\Parameters\Keys> cd deadbeef0000

(...)\BTHPORT\Parameters\Keys\deadbeef0000> ls
Node has 0 subkeys and 3 values
  size     type              value name             [value if type DWORD]
    16  3 REG_BINARY         <0123456789ab>

(...)\BTHPORT\Parameters\Keys\deadbeef0000> hex 0123456789ab
Value <0123456789ab> of type REG_BINARY (3), data length 16 [0x10]
:00000  XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX ..R..D.Yb.q.M<j.

ここで deadbeef0000 は Bluetooth インターフェースの MAC アドレス,0123456789ab はペアリングした Bluetooth 周辺機器の MAC アドレスである。 これは各自の環境の値に置き換えてほしい。 ここで,最後に出てきた XX XX XX XX .. XX となっている部分,これが実際には 16 進数 32 ケタで記述されたペアリングキーである。 これら,インターフェースの MAC周辺機器の MACペアリングキー の組をメモしたら,次のステップである。

最後に, /var/lib/bluetooth/<インターフェースの MAC>/<周辺機器の MAC>/info を編集する。 このファイルの [LinkKey] セクションにある Key= の部分を,メモしたペアリングキーに置き換える。 その後に,

systemctl restart bluetooth
とすればおっけー。これで Linux でも Windows でも接続できるはずである。

追記

BLE の場合,LinkKey でなくいくつか複数の値が必要な模様 https://unix.stackexchange.com/questions/402488/dual-boot-bluetooth-device-pairing

具体的には

  • IRK を [IdentityResolvingKey] の Key= へ
  • CSRK を [LocalSignatureKey] の Key= へ
  • LTK を [LongTermKey] の Key= へ
  • ERand を Rand へ。ただし,たとえば 16 進数で ab cd ef とあればこれを逆順にした (ef cd ab) 上で 10 進数に変換する必要アリ
  • EDIV を EDiv へ。ただし 16 進数から 10 進数へ変換する必要アリ