Linux/Windowsのデュアルブート環境でBluetoothやBLEのデバイスを共有する方法
私のPCは普段使いのGentoo LinuxとゲームとかCADとか用のWindowsの両方をインストールしてあります。 そんなデュアルブート環境だと、OSを変えるたびにBluetoothデバイスを再ペアリングする必要があってちょっと面倒臭いことになります。
この原因は、ペアリングのときに生成されるキーをOS間で共有出来ないことにあるようです。 デバイスから見ると、「同じMACアドレスを名乗っているのに約束していたキーと違う。偽物だ!」みたいな感じらしいです。
調べてみたら結構簡単に合せられるっぽいので、設定してみました。 Bluetoothの場合とBluetooth LEの場合で一部手順が違うので、お使いのデバイスに合わせて対応してください。
1. Linux側でペアリングする
Windows側で生成したキーにLinux側を合せる手順を取るので、LinuxでペアリングしてからWindowsでペアリングする順序にします。 というわけで、まずはLinuxで普通にペアリング。
接続すると、/var/lib/bluetooth/{レシーバのmacアドレス}/{デバイスのmacアドレス}
の中に接続情報が書かれたファイルが生成されるはずです。
2. Windows側でペアリングする
今度はWindowsを起動して、もう一度ペアリングします。
ここでWindowsとデバイス間で作られたキーの情報を使って接続するようにします。 別にLinux側で作ったやつをWindows側に持っていっても良いと思うのだけれど、Linux側の方がいじりやすいので。
3. Windowsのレジストリから情報を取り出す
Windowsが作ったキーが欲しいので、レジストリの以下の場所にある情報をエクスポートします。
HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\BTHPORT\Parameters\Keys
これを適当なエディタで開いて確認してみると、以下のような内容になっているはずです。 文字コードがUTF-16LEなので注意。
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\BTHPORT\Parameters\Keys]
[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\BTHPORT\Parameters\Keys\001bdcxxxxxx]
"MasterIRK"=hex:08,ce,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx
"cc988bxxxxxx"=hex:84,ed,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx
[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\BTHPORT\Parameters\Keys\001bdcxxxxxx\d3bc56xxxxxx]
"LTK"=hex:a8,76,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,f8
"KeyLength"=dword:00000010
"ERand"=hex(b):eb,00,00,00,00,00,00,89
"EDIV"=dword:00ab0123
"MasterIRKStatus"=dword:00000001
"AuthReq"=dword:0000002d
4. Linuxに戻って接続情報を編集する
Linuxに戻って、/var/lib/bluetooth/{レシーバのmacアドレス}/{デバイスのmacアドレス}/info
を開きます。
レシーバとデバイスのmacアドレスは以下のコマンドで見付けられると思います。
# レシーバの一覧
$ bluetoothctl list
Controller 00:1B:DC:XX:XX:XX hostname [default]
# ペアリングしているデバイスの一覧
$ bluetoothctl devices
Device D3:BC:56:XX:XX:XX Microsoft Bluetooth Mouse
Device CC:98:8B:XX:XX:XX WH-1000XM3
ここからは、Bluetoothの場合とBluetooth LEの場合で分岐します。
開いたinfo
ファイルの中に[LinkKey]
という記述がある場合はBluetoothの場合に、[LongTermKey]
という記述がある場合はBluetooth LEの場合に進んでください。
Bluetoothの場合
必要な情報を探す
Windows側でエクスポートした.regファイルから、以下のようなセクションを見つけます。
[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\BTHPORT\Parameters\Keys\001bdcxxxxxx]
"MasterIRK"=hex:08,ce,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx
"cc988bxxxxxx"=hex:84,ed,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx
Keys\001bdcxxxxxx
の部分がレシーバのmacアドレスになっているはずです。
この中からデバイスのmacアドレスと対応する値を見つけ出してコピーします。
今回は"cc988bxxxxxx"
とペアリングしたいので、84,ed,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx
の部分をコピーします。
カンマは不要なので削除して、ついでにLinux側に合わせて大文字にしておきます。(小文字でも別に良いっぽいけれど)
ファイルに反映する
コピーしてカンマを消した値を使って、Linux側のinfo
ファイルを以下のような感じで編集します。
[LinkKey]
Key=84EDXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Type=4
PINLength=0
これでキーの移行は完了です。
Bluetooth LEの場合
必要な情報を探す
Windows側でエクスポートした.regファイルから、以下のようなセクションを見つけます。 Bluetoothの場合と違って結構長いです。
[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\BTHPORT\Parameters\Keys\001bdcxxxxxx\d3bc56xxxxxx]
"LTK"=hex:a8,76,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,f8
"KeyLength"=dword:00000010
"ERand"=hex(b):eb,00,00,00,00,00,00,89
"EDIV"=dword:00ab0123
"MasterIRKStatus"=dword:00000001
"AuthReq"=dword:0000002d
Keys\001bd0cxxxxxx
の部分がレシーバのmacアドレスで、その後に続く\d3bc56xxxxxx
の部分がデバイスのmacアドレスになっています。
複数デバイスある場合はこのセクションが複数あるはずなので、必要なものを見つけてください。
加工する
ここで必要なのは以下の3つの情報です。 ついでに色々加工をします。
- LTK:
hex:
の後ろのa8,76,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,f8
からカンマを取って、A876XXXXXXXXXXXXXXXXXXXXXXXXXXF8
のようにして使います。 - ERand:
hex(b):
の後ろのeb,00,00,00,00,00,00,89
を左右反転(89,00,00,00,00,00,00,eb
)してカンマを取って、10進数(9871890383196127467
)にして使います。 - EDIV:
dword:
の後ろの00ab0123
を10進数にして、11206947
のようにして使います。
諸々の変換はPythonとか使うと楽かもしれません。
>>> # LTKの加工
>>> 'a8,76,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,f8'.replace(',', '').upper()
A876XXXXXXXXXXXXXXXXXXXXXXXXXXF8
>>> # ERandの加工
>>> int(''.join(reversed('eb,00,00,00,00,00,00,89'.split(','))), 16)
9871890383196127467
>>> # EDIVの加工
>>> int('00ab0123', 16)
11206947
ファイルに反映する
加工した情報を使って、Linux側のinfo
ファイルのLongTermKey
セクションを以下のように書き換えます。
[LongTermKey]
Key=A876XXXXXXXXXXXXXXXXXXXXXXXXXXF8
Authenticated=0
EncSize=16
EDiv=11206947
Rand=9871890383196127467
値はそれぞれ、LTK
→Key
、ERand
→Rand
、EDIV
→EDiv
になります。
5. Bluetoothデーモンを再起動して確認する
これで、Windows側で生成したキーをLinux側でも使えるようになっているはずです。 変更を反映させるために、デーモンを再起動させましょう。
$ sudo systemctl restart bluetooth
問題無く設定出来ていれば、再ペアリングすることなく両方のOSから接続出来るようになっているはずです。 やったね。
参考: