Matter 14 · 運用時のセキュリティとマルチアドミン — CASE・ACL・Fabric

Chapter 14

運用時のセキュリティとマルチアドミン — CASE・ACL・Fabric

この章がなぜ必要なのか——「複数のエコシステムに同時対応」が Matter の売りだから.

Apple Home と Google Home に同じ電球を登録できる—— これは Matter の最大の差別化要因である。

だが技術的には難しい。互いを信頼しない複数の管理者が、 同じ機器を同時に管理するからである。

そして実装で最も多いバグの源でもある。 「1 つ目のエコシステムでは動くが 2 つ目で失敗する」は定番の症状である。

この章で使う既出の用語(定義は各リンク先). Matter(01 章 3 節)、コミッショニング(01 章 3 節)、セキュリティ(01 章 2 節)、ネットワーク(01 章 3 節)、ACL(02 章 4 節)、Administrator(02 章 5 節)、Cluster(02 章 2 節)、Endpoint(02 章 2 節)、Report(02 章 6 節)、マルチキャスト(03 章 3 節)、Wi-Fi(04 章 9 節)、必要(05 章 5 節)、Group(06 章 4 節)、PASE(06 章 4 節)、コミッショナ(06 章 1 節)、運用時(06 章 4 節)、NodeLabel(08 章 1 節)、Fail-Safe(09 章 9 節)、Administer(11 章 8 節)、IPK(11 章 3 節)、Manage(11 章 8 節)、Operate(11 章 8 節)、ProxyView(11 章 8 節)、乱数(11 章 2 節)、盗聴(11 章 1 節)、署名(11 章 2 節)、証明書(11 章 5 節)、鍵交換(11 章 2 節)、DAC(12 章 11 節)

1. CASE — 運用時のセッション確立

Certificate Authenticated Session Establishment。 双方が同じ Fabric の NOC を持っていることを相互に確認する。

イニシエータ                            レスポンダ
    │                                    │
    │──── Sigma1 ──────────────────────>│  乱数、エフェメラル公開鍵、
    │                                    │  暗号化された宛先識別子
    │<─── Sigma2 ───────────────────────│  乱数、エフェメラル公開鍵、
    │                                    │  暗号化された NOC と署名
    │──── Sigma3 ──────────────────────>│  暗号化された NOC と署名
    │<─── StatusReport (成功) ───────────│
    │                                    │
    └──── セッション鍵を導出、以降暗号化通信 ─┘
特徴内容
SIGMA プロトコル相互認証付き鍵交換。ECDH(P-256)+ ECDSA 署名
アイデンティティ保護証明書は暗号化されて送られる。盗聴者に身元が漏れない
前方秘匿性エフェメラル鍵を使うので、長期鍵が漏れても過去の通信は復号できない
IPK の役割宛先識別子の生成に使われ、Fabric の一致を確認する

なぜ証明書を暗号化するのか. 平文で NOC を送ると、盗聴者に「この家には Node ID 0x42 の機器がいる」と分かる。 プライバシーのため、Sigma2/Sigma3 の中身は暗号化される。

CASE Resumption

一度確立したセッションの情報を保持しておき、次回は短縮した手順で再確立する。

効果内容
ECDSA 署名検証を省略組み込み機器では大きな節約(署名検証は重い)
ラウンドトリップの削減応答が速い
電池の節約特に SED で効く

P-256 の署名検証は、Cortex-M クラスの MCU で数十〜数百 ms かかる. ハードウェアアクセラレータがなければ、CASE 確立に 1 秒近くかかることもある。 Resumption の実装は、体感速度に直結する。

2. Fabric の構造

Fabric(1 つのエコシステムの管理ドメイン)
 ├── Root CA 証明書(RCAC)      … この Fabric の信頼の根
 ├── Fabric ID(64 bit)
 ├── IPK(Identity Protection Key)
 └── 所属する Node たち
      └── 各 Node の NOC(Root CA が発行)

機器側から見ると、Fabric ごとに以下を保持する。

保持するものサイズの目安
RCAC数百 byte
ICAC(任意)数百 byte
NOC数百 byte
操作用秘密鍵32 byte(+ 保護のオーバーヘッド)
IPK16 byte
ACL エントリ数百 byte
グループ鍵数十 byte × グループ数
Fabric Label32 byte

1 Fabric あたり 1〜2 KB は見ておく必要がある. 5 Fabric なら 5〜10 KB。RAM ではなく不揮発メモリを消費する。 SupportedFabrics を大きく宣言するなら、フラッシュの余裕を確保すること(17 章)。

Fabric Index

機器内部での Fabric の通し番号(1 から始まる 8 bit)。 Fabric-Scoped な属性(07 章)はこれで所属を区別する。

Fabric Index は機器のローカルな値である. 同じ Fabric でも、機器 A では Index 1、機器 B では Index 2 かもしれない。 グローバルな識別子ではないので、コントローラ間で共有してはいけない。

3. ACL — アクセス制御リスト

AccessControl クラスタ (0x001F) の ACL 属性。Fabric-Scoped である。

エントリの構造

フィールド内容
PrivilegeView / ProxyView / Operate / Manage / Administer
AuthModePASE / CASE / Group
Subjects対象の Node ID のリスト(または CAT、Group ID)。空 = 全員
Targets対象の {Cluster, Endpoint, DeviceType}。空 = すべて
FabricIndex所属 Fabric(自動設定)

判定のルール

要求(Subject, 操作対象のパス, 必要な特権)が来る
   ↓
その Fabric の ACL エントリを順に見る
   ↓
以下をすべて満たすエントリが 1 つでもあれば許可:
   - AuthMode が一致
   - Subjects が空、または要求元の Node ID を含む
   - Targets が空、または対象のパスに一致
   - Privilege が必要な特権以上
   ↓
1 つもなければ UNSUPPORTED_ACCESS (0x7E)

「拒否」のエントリは存在しない. 許可リストだけである。 だから ACL が空なら誰も何もできない。

コミッショニング時に AddNOC の CaseAdminSubject から 自動生成される 1 件目のエントリが、この状態を脱するための入口である(13 章)。

特権の階層

Administer  ⊃  Manage  ⊃  Operate  ⊃  View

上位は下位をすべて含む。ProxyView は View と同等の読み取りに使われる特殊な特権である。

CAT(CASE Authenticated Tag)

NOC の Subject に含められるタグ。個別の Node ID ではなく、 「このタグを持つ者」という単位で ACL を書ける。

ACL エントリ: { Privilege: Operate, AuthMode: CASE, Subjects: [CAT 0x0001_0001] }
   → CAT 0x0001_0001 を持つ NOC の保持者は誰でも Operate できる
用途内容
管理者の追加新しいコントローラに同じ CAT の NOC を発行すれば、ACL を変えずに権限が付く
バージョン管理CAT の下位 16 bit がバージョン。古い版を無効化できる

CAT は大規模なエコシステムで必須になる. 家族 5 人のスマホそれぞれに Node ID があるとき、 全機器の ACL に 5 つの Node ID を書くのは非現実的である。 CAT を 1 つ書いておけば、新しい端末は NOC の発行だけで参加できる。

4. マルチアドミン — 2 つ目のエコシステムを追加する

[すでに Apple Home にコミッショニング済みの電球]
   ↓
1. ユーザーが Apple Home で「他のプラットフォームに追加」を選ぶ
   ↓
2. Apple Home が AdministratorCommissioning.OpenCommissioningWindow を送る
      - 新しい PAKE 検証子(新しい一時的な passcode に対応)
      - タイムアウト(最大 15 分)
   ↓
3. 新しい QR コード(またはコード)が Apple Home の画面に表示される
   ↓
4. ユーザーが Google Home でそれを読む
   ↓
5. Google Home が PASE → 認証 → 自分の Fabric の NOC を発行して AddNOC
   ↓
6. 機器が 2 つ目の Fabric に所属する
コマンド内容
OpenCommissioningWindow新しい検証子を渡してウィンドウを開く(推奨)
OpenBasicCommissioningWindow元の passcode でウィンドウを開く(機器の対応は任意)
RevokeCommissioningウィンドウを閉じる

OpenCommissioningWindow が推奨される理由. 元の passcode(QR コードに印刷されている)を再利用すると、 箱や本体のラベルを見た人が誰でも参加できる。

新しい一時的な検証子を使えば、その場で表示された値を知る者だけが参加できる。 時間制限もあるので、より安全である。

Enhanced Multi-Admin(1.4 以降)

QR コードの手動読み取りを不要にし、エコシステム間で直接連携して機器を共有する仕組み。 ユーザー体験の改善が目的である。対応は各エコシステムの実装次第となる。

5. Fabric の管理

コマンド/属性内容
OperationalCredentials.Fabrics所属している Fabric の一覧(Fabric-Sensitive)
OperationalCredentials.SupportedFabrics対応可能な最大数
OperationalCredentials.CommissionedFabrics現在の所属数
UpdateFabricLabelユーザー向けのラベルを設定
RemoveFabricFabric から離脱

Fabrics 属性は Fabric-Sensitive である. Apple Home から読むと、Google Home の Fabric の詳細(ラベルなど)は隠される。 「他にいくつ所属しているか」は分かるが、中身は見えない——これが仕様の意図である。

RemoveFabric の注意

RemoveFabric(fabricIndex)
   ↓
その Fabric の NOC・鍵・ACL・グループ鍵・サブスクリプションをすべて削除
   ↓
所属 Fabric が 0 になったら → ファクトリリセット相当の状態に戻る

自分自身の Fabric を削除すると、応答が返らないことがある. セッションが即座に無効になるためである。 コントローラ側は「応答なし」を成功として扱う必要がある。

6. グループ通信のセキュリティ

グループコマンド(09 章)はマルチキャストで、CASE セッションを使わない。 代わりにグループ鍵で保護する。

Group Key Management クラスタ
 ├── GroupKeySet(鍵の集合。Epoch キーを 3 世代まで持てる)
 └── GroupKeyMap(Group ID ↔ GroupKeySet の対応)
特徴内容
Fabric-ScopedFabric ごとに独立
Epoch キー世代交代できる。古い鍵と新しい鍵を並行して受け入れる期間がある
対称鍵グループの全メンバーが同じ鍵を持つ

グループ鍵は「グループの誰か 1 台が漏れたら全部漏れる」構造である. 対称鍵なので原理的にこうなる。 だからグループ通信は重要度の低い操作に限るのが設計上の原則である。 ドアロックの解錠をグループコマンドで行うべきではない。

Epoch キーのローテーションは、この弱さを緩和するための仕組みである。

7. ファクトリリセット

トリガ例
物理ボタンの長押し最も一般的
全 Fabric の削除RemoveFabric の結果
特定の手順電源の入切を N 回など

消すべきもの:

消してはいけないもの:

中古品・返品されて再販される機器で、これが決定的に重要になる. 前の持ち主の Wi-Fi パスワードが残っていたら重大な事故である。

ファクトリリセットの完全性は、認証テストでも確認される。 「消したつもりで消えていない」を防ぐため、リセット後に実際にフラッシュを ダンプして確認するテストを開発工程に入れるべきである。

8. 落とし穴

落とし穴内容
ACL の設定漏れUNSUPPORTED_ACCESS (0x7E) の主因。最頻出
Fabric-Scoped の実装ミス他 Fabric の設定を消す・見せてしまう
Fabric 数の見積り不足2〜3 個目で RESOURCE_EXHAUSTED
不揮発メモリの不足Fabric 追加で書き込み失敗
CASE Resumption 未実装再接続が遅い(特に電池機器)
ウィンドウを閉じ忘れる誰でも参加できる状態が残る
RemoveFabric の応答待ち自分自身を削除すると応答が来ない
ファクトリリセットの不完全性前の持ち主の情報が残る
グループ鍵の Epoch 管理ミス鍵交代時に通信が途切れる
時刻のずれ証明書の有効期限判定に影響しうる

「1 つ目は動くが 2 つ目で失敗する」の診断.

  1. CommissionedFabrics と SupportedFabrics を読む → 上限に達していないか
  2. 不揮発メモリの空きを確認 → 書き込み失敗していないか
  3. Fabric-Scoped 属性の実装を確認 → 1 つ目の設定を上書きしていないか
  4. ACL を読む → 2 つ目の Fabric のエントリが作られているか
  5. Fail-Safe の巻き戻しを確認 → 前回の失敗が残っていないか

開発中は必ず 3 つ以上の Fabric でテストすること。 chip-tool は --commissioner-name で複数の Fabric を扱える。

# 2 つ目の Fabric として追加する(chip-tool)
# まず既存の管理者としてウィンドウを開く
chip-tool pairing open-commissioning-window 1 1 300 1000 3840
# → 表示された manual code / QR で別のコミッショナから参加
chip-tool --commissioner-name beta pairing code 1 <code>

# Fabric の一覧を確認
chip-tool operationalcredentials read fabrics 1 0
chip-tool operationalcredentials read commissioned-fabrics 1 0

# ACL を確認
chip-tool accesscontrol read acl 1 0

9. まとめ