Matter 13 · コミッショニング — QR コードから Fabric 参加まで

Chapter 13

コミッショニング — QR コードから Fabric 参加まで

この章がなぜ必要なのか——最も失敗しやすく、最もユーザー体験を左右する部分.

ユーザーが Matter 機器に触れる最初の瞬間がコミッショニングである。 ここで失敗すれば返品される。

そして開発者にとっては、最も多くの要素が絡む工程でもある。 BLE・IPv6・mDNS・SPAKE2+・証明書検証・ネットワーク設定・NOC 発行—— どれか 1 つでも狂えば「見つかりません」で終わる。

この章では全手順を追い、それぞれで何が失敗しうるかを示す。

この章で使う既出の用語(定義は各リンク先). Matter(01 章 3 節)、コミッショニング(01 章 3 節)、ネットワーク(01 章 3 節)、ACL(02 章 4 節)、Administrator(02 章 5 節)、IPv6(02 章 1 節)、Node(02 章 2 節)、mDNS(03 章 4 節)、Wi-Fi(04 章 9 節)、BLE(05 章 1 節)、必要(05 章 5 節)、PASE(06 章 4 節)、SRP(06 章 2 節)、Fail-Safe(09 章 9 節)、Administer(11 章 8 節)、IPK(11 章 3 節)、パスコード(11 章 5 節)、盗聴(11 章 1 節)、総当たり(11 章 1 節)、署名(11 章 2 節)、証明書(11 章 5 節)、DAC(12 章 11 節)、メーカー(12 章 3 節)

1. 全体の流れ

[0] 機器がコミッショニング可能な状態で待つ(BLE / mDNS で広告)
      ↓
[1] ユーザーが QR コードをスキャン(または手動コードを入力)
      ↓  → passcode / discriminator / VID / PID を得る
[2] コントローラが機器を発見(BLE アドバタイズ or mDNS)
      ↓
[3] PASE セッション確立(SPAKE2+、passcode が根拠)
      ↓  ← ここから通信が暗号化される
[4] ArmFailSafe(失敗したら巻き戻すタイマーを開始)
      ↓
[5] デバイス認証(AttestationRequest → DAC / PAI / CD を検証)
      ↓
[6] CSRRequest → 機器が操作用鍵ペアを生成、CSR を返す
      ↓
[7] コントローラが NOC を発行
      ↓
[8] AddTrustedRootCertificate(Fabric のルート証明書を渡す)
      ↓
[9] AddNOC(NOC・ICAC・IPK・Admin Subject・Vendor ID を渡す)
      ↓  ← ここで Fabric が仮追加される
[10] ネットワーク設定(Wi-Fi 認証情報 or Thread Dataset)
      ↓
[11] 機器が運用ネットワークに参加
      ↓
[12] コントローラが運用ネットワーク上で機器を再発見(mDNS)
      ↓
[13] CASE セッション確立(NOC が根拠)
      ↓
[14] CommissioningComplete(Fail-Safe を解除、Fabric を確定)
      ↓
[15] BLE 切断、コミッショニング広告を停止

[11]〜[13] が「トランスポートの切り替え」である. ここまでは BLE 上で話していたが、以降は Wi-Fi / Thread の IP 通信になる。 この切り替えが最も失敗しやすい。機器がネットワークに入れない、 入ったが mDNS で見つからない、といったトラブルがここで出る。

2. オンボーディングペイロード(QR コード)

QR コードには以下が 88 bit にパックされ、Base38 でエンコードされている。

フィールドビット数内容
Version3ペイロードのバージョン(現在 0)
Vendor ID16メーカー
Product ID16製品
Custom Flow20=標準、1=ユーザー操作が必要、2=カスタム
Discovery Capabilities8ビットマスク(bit0=SoftAP, bit1=BLE, bit2=既存ネットワーク上, bit3=Wi-Fi PAF …)
Discriminator12機器の絞り込み用(0〜4095)
Passcode27セットアップパスコード(1〜99999998)
Padding40 埋め
合計88 bit = 11 byte

Base38 エンコード

文字集合0-9, A-Z, -, . の 38 文字
3 byte → 5 文字\(38^5 = 79{,}235{,}168 > 2^{24}\)
2 byte → 4 文字\(38^4 = 2{,}085{,}136 > 2^{16}\)
1 byte → 2 文字\(38^2 = 1{,}444 > 2^{8}\)

11 byte = 3 byte × 3 + 2 byte なので、5×3 + 4 = 19 文字。 先頭に MT: が付き、QR コード全体は 22 文字になる。

MT:Y.K9042C00KA0648G00

ビットパックは LSB 側から詰める(リトルエンディアン的な順序)である。 実装するときは仕様の 5.1.3 節を精読すること。 バイト順を間違えると、まったく別の値としてデコードされる—— しかも「不正なコード」ではなく「別の有効な値」になるので、気づきにくい。

3. 手動ペアリングコード

QR コードが読めない場合(印刷が擦れた、カメラがない)のために、 数字だけのコードが併記される。

11 桁版(VID/PID なし)

位置桁数内容
11`(VID/PID 有無) << 2 \(discriminator >> 10)`
2〜65`((discriminator & 0x300) << 6) \(passcode & 0x3FFF)`
7〜104passcode >> 14
111Verhoeff チェックディジット

21 桁版(VID/PID あり)

11 桁版の 10 桁目のあとに VID(5 桁)と PID(5 桁)が入り、最後にチェックディジット。

手動コードには Discriminator の上位 4 bit しか入らない. 12 bit のうち bit 8〜11 だけである(Short Discriminator)。 だから mDNS のサブタイプに _S<n>(Short)と _L<n>(Long)の両方がある(06 章)。

4 bit = 16 通りしかないので、周囲に同じ製品が複数あると絞り込めない。 QR コードの方が確実である。

Verhoeff チェックディジット

入力ミスを検出するアルゴリズム。単純な mod 10 より強力で、 隣接する桁の入れ替え(1234 → 1243)も検出できる。

二面体群 \(D_5\) の演算表・置換表・逆元表を使う。

人間が手で入力する前提なので、打ち間違いの検出が重要である. 最も多い入力ミスは「1 桁間違い」と「隣接 2 桁の入れ替え」である。 Verhoeff はこの両方を 100% 検出する。

4. Passcode の制約

項目内容
範囲1 〜 99,999,998
ビット数27 bit
禁止値00000000, 11111111, 22222222, …, 88888888, 99999999, 12345678, 87654321

禁止値がある理由. 推測されやすい値を排除するため。総当たりの最初に試される値である。

さらに重要: 個体ごとに違う値にすること。 SDK のデフォルト 20202021 を製品に使うと、 誰でもその製品をコミッショニングできる。 製造時にランダムに生成し、SPAKE2+ の検証子を計算して焼き込む(12 章)。

5. PASE — SPAKE2+ によるセッション確立

コントローラ                            機器
    │                                    │
    │──── PBKDFParamRequest ───────────>│  (ランダム、セッション ID)
    │<─── PBKDFParamResponse ───────────│  (salt, iterations を返す)
    │                                    │
    │  passcode + salt + iterations       │  (検証子 w0, L は保存済み)
    │  → PBKDF2 → w0, w1                 │
    │                                    │
    │──── Pake1 (X) ───────────────────>│
    │<─── Pake2 (Y, cB) ────────────────│
    │──── Pake3 (cA) ──────────────────>│
    │<─── PakeFinished ─────────────────│
    │                                    │
    └──── 共有鍵を導出、以降は暗号化通信 ───┘
要点内容
機器はパスコードを保存しない検証子(w0, L)だけを持つ(11 章)
盗聴者はオフライン総当たりできないSPAKE2+ の性質
相互認証双方が正しいパスコードを知っていることを確認
PBKDF2 の反復回数1000 以上(仕様の下限)。機器の計算能力とのトレードオフ

PBKDF2 の反復回数が組み込み機器では効く. 反復回数が多いほど安全だが、低速な MCU では数秒かかる。 ユーザーは「反応がない」と感じる。

検証子を工場で事前計算しておけば、機器側は PBKDF2 を実行しなくてよい。 これが実装上の定石である(コントローラ側だけが PBKDF2 を回す)。

試行回数の制限

オンライン攻撃への対策は機器側の責任である. SPAKE2+ は「1 回の通信で 1 つのパスコードしか試せない」ことを保証するが、 何度も試すことは止められない。

仕様は、失敗が続いたらコミッショニングウィンドウを閉じることを求めている。 実装で必ず対応すること。 無制限に試行を許すと、27 bit のパスコードは破られうる。

6. Commissioning Window

機器がコミッショニング可能な状態でいる時間。

状態いつ
初期状態工場出荷時/ファクトリリセット後。自動的に開く
追加のウィンドウ既存の管理者が AdministratorCommissioning クラスタで開く(14 章のマルチアドミン)
項目値
最小時間3 分(180 秒)
最大時間15 分(900 秒)

ウィンドウは必ず閉じること. 開きっぱなしだと、パスコードを知る者が誰でも参加できる。 タイムアウト、成功時、失敗回数超過——いずれでも確実に閉じる実装が必要である。

またウィンドウが開いている間は _matterc._udp を広告するので、 閉じたら広告も止める。

7. ネットワーク設定

Network Commissioning クラスタ (0x0031) を使う。

Wi-Fi の場合

ScanNetworks              ← 周囲の SSID を取得(任意)
AddOrUpdateWiFiNetwork    ← SSID と credentials を渡す
ConnectNetwork            ← 接続を指示

Thread の場合

ScanNetworks                ← 周囲の Thread ネットワークを取得(任意)
AddOrUpdateThreadNetwork    ← Operational Dataset(TLV バイト列)を渡す([04 章](04_Thread.md#operational-dataset-thread-の-ネットワーク設定))
ConnectNetwork              ← 参加を指示

ConnectNetwork の応答が返る前に、機器はネットワークに移動する. BLE の接続が切れることもある。 コントローラ側は「応答が来ないこと」を異常と決めつけず、 運用ネットワーク上での再発見に進む必要がある。

ここの実装が甘いと「コミッショニングが 90% で止まる」症状になる。

8. NOC の発行

CSRRequest(nonce)
    ↓
機器: 操作用の鍵ペアを生成(P-256)、CSR を作成、DAC 秘密鍵で署名
    ↓
CSRResponse(NOCSRElements, AttestationSignature)
    ↓
コントローラ: 署名を検証 → CA に NOC の発行を依頼
    ↓
AddTrustedRootCertificate(RCAC)
AddNOC(NOC, ICAC, IPK, CaseAdminSubject, AdminVendorId)
    ↓
機器: Fabric を仮追加(Fail-Safe 下)
パラメータ内容
NOCこの機器の運用証明書(Node ID を含む)
ICAC中間 CA(任意)
IPKIdentity Protection Key(Fabric 共有)
CaseAdminSubject管理者となる Node ID(または CAT)
AdminVendorId管理者エコシステムの VID

CaseAdminSubject が最初の ACL エントリになる. AddNOC の直後、機器は「この Subject に Administer 権限を与える」ACL を自動生成する。 これがないと、コミッショニング直後に誰も機器を操作できなくなる(14 章)。

9. コミッショニングの種類

方式内容
標準(Standard Commissioning Flow)QR を読んで即座に開始できる
User-Intentユーザーが機器のボタンを押すなどの操作が必要
Customメーカーのアプリなどで事前準備が必要

Custom Flow フィールド(QR ペイロードの 2 bit)で示される。

可能なかぎり標準フローにすべきである. ユーザーが「箱から出して QR を読むだけ」で終わるのが理想。 Custom Flow は「メーカーのアプリを先にインストールしてください」という 体験になり、Matter の利点を大きく損なう。

User Directed Commissioning (UDC)

テレビなどの機器が「私をコミッショニングしてください」と コントローラ側に働きかける方式。_matterd._udp を使う。

リモコンで QR コードを読むのが難しい機器(大型テレビなど)で使われる。

10. 落とし穴と診断

症状疑うべきこと
BLE で見つからないアドバタイズしていない/Discriminator の不一致/BLE の権限(スマホ側)
PASE で失敗passcode の不一致/検証子の計算ミス/salt・iterations の不整合
Attestation で失敗証明書チェーン/CD と DAC の VID/PID 不一致/PAA が信頼されていない
ネットワーク参加で失敗Wi-Fi パスワード/Thread Dataset の誤り/電波
参加後に見つからないmDNS / SRP の問題(03 章・06 章)。最頻出
CASE で失敗NOC の内容/時刻/IPK の不一致
90% で止まるConnectNetwork 後の再発見が失敗している
2 回目以降のコミッショニングが失敗Fabric の上限に達している/前回の失敗が巻き戻っていない

診断の順序

1. 機器のログで、どこまで進んだかを確認
      ↓
2. BLE で見つからない → 広告の確認、スマホ側の Bluetooth 権限
      ↓
3. PASE 失敗 → passcode / 検証子
      ↓
4. Attestation 失敗 → 証明書。開発中なら --paa-trust-store-path を確認
      ↓
5. ネットワーク参加失敗 → 認証情報、Dataset
      ↓
6. 再発見失敗 → dns-sd / ot-ctl srp server service([06 章](06_探索とメッセージング.md#見つからない-とき))
      ↓
7. CASE 失敗 → NOC、時刻、ACL
# chip-tool でのコミッショニング例
# BLE + Wi-Fi
chip-tool pairing ble-wifi 1 <SSID> <PASSWORD> 20202021 3840
# BLE + Thread
chip-tool pairing ble-thread 1 hex:<dataset> 20202021 3840
# すでに同じネットワーク上にいる機器(開発時に便利)
chip-tool pairing onnetwork 1 20202021
# QR コードから
chip-tool pairing code 1 MT:Y.K9042C00KA0648G00
# 手動コードから
chip-tool pairing code 1 34970112332

開発中は pairing onnetwork が最速である. Linux 上のサンプルアプリなら BLE もネットワーク設定も要らない。 まずこれで動かし、次に BLE 経由を試すという順序が効率的である。

11. まとめ