🫣

ESPHome × sesame が突然ビルド失敗するようになった話

に公開

家で導入しているsesame5くんのWi-FiモジュールをHomeAssistantのESPHomeで代用しているのですが、いろいろアップデートしてたら気付いたら動かなくなりました。
苦労したのでメモも兼ねてこちらに記載します。

当時参考にさせて頂いた記事
https://maky-ba.hatenablog.com/entry/2024/06/24/192418

症状

ESPHome(2025.7.x)で SESAME(外部コンポーネント)をビルドしたところ、コンパイルが次のようなエラーで止まるようになりました。

MBEDTLS_CIPHER_BLKSIZE_MAX undeclared

mbedtls_cipher_context_tcipher_infoが無い
mbedtls_cmac_context_tunprocessed_lenなどにアクセスできない(private化)
※CMAC(AES-CMAC)まわりで大量のビルドエラー。

結論

Arduino-ESP32 3.x系(ESPHome 2025.7.x のデフォルト構成)が内部でmbedTLS 3系に上がった
mbedTLS 3では構造体の中身が非公開化・一部マクロ削除などの破壊的変更が入った

ところが、私の環境ではSESAMEライブラリが「独自のCMAC実装(mbedTlsの内部構造に触るやつ)」をコンパイルしてしまうルートに入っていた。

そのため旧コードがmbedTLS 3の世界で爆散.....

対策

・SESAME 外部コンポーネントを新しめに上げる
・ビルドフラグで「フレームワーク(mbedTLS)のCMAC実装を使え」と明示する

合わせて、ESPHome側のスキーマも変更(非推奨→新形式)に追随が必要でした。

何が変わったのか

1) mbedTLS 2 → 3 の的変更
mbedTLS 3ではセキュリティと将来互換性のために、多くの構造体が “opaque(不透明)” になりました。
例)
mbedtls_cipher_context_tの内部フィールドを直接参照できない(ctx->cipher_info等NG)
mbedtls_cmac_context_tのワークバッファや長さフィールドがprivate化(unprocessed_lenなどに直接触れない)
一部のマクロ(MBEDTLS_CIPHER_BLKSIZE_MAXなど)が廃止・移動

つまり、内部に手を突っ込む系の独自実装は壊れるというのが今回の本質です。

2) CMAC は “自前実装” ではなく “フレームワーク実装” に寄せる
SESAME 連携ライブラリ(libsesame3bt)には、mbedTLS 2時代の名残としてmbedtls-extra/cmac.*による自前CMAC実装が入っています。
本来、mbedTLS 3ではmbedtls/cmac.hが提供する公式APIで完結させるべきですが、
「ビルドの条件分岐」次第では、誤って“自前CMAC”の古いコードパスが選ばれ、今回のような大量エラーになります。

3) ESPHome の “lock” スキーマも刷新
エラーログにはUsing lock.LOCK_SCHEMA is deprecatedという警告も出ていました。
ESPHomeでは古い書き方(platform: sesame_lock + 旧スキーマ)が非推奨になり、
新しいsesame:ブロック+ lock.lock_schema()ベースへ移行しています。
こちらは警告レベルですが、将来の破綻要因なので早めに直すのが吉。

私の環境で実際に起きていたこと。
・**外部コンポーネントのバージョンが古い(v0.10.0)**ままだった
・ビルドフラグに “フレームワークCMACを使う” 指示が無い

そのため、ライブラリの自前CMACコードがビルドされる→mbedTLS 3と衝突
さらにlibraries:libsesame3btを個別指定しており、依存解決が二重化・齟齬を起こす可能性

対策(動いた設定)

2行のビルドフラグと外部コンポーネントの更新、旧スキーマ撤廃です。

my-esp.yaml
esphome:
  name: sesame
  friendly_name: sesame
  platformio_options:
    build_flags:
      - -std=gnu++17 -Wall -Wextra
      - -DMBEDTLS_DEPRECATED_REMOVED
      - -DCONFIG_BT_NIMBLE_ROLE_BROADCASTER_DISABLED
      - -DCONFIG_BT_NIMBLE_ROLE_PERIPHERAL_DISABLED
      - -DCONFIG_BT_NIMBLE_MAX_CONNECTIONS=4
      # これか重要。フレームワーク(mbedTLS)のCMACを使わせる
      - -DCONFIG_MBEDTLS_CMAC_C
      - -DUSE_FRAMEWORK_MBEDTLS_CMAC
    build_unflags:
      - -std=gnu++11
    lib_ldf_mode: deep

external_components:
  - source:
      type: git
      url: https://github.com/homy-newfs8/esphome-sesame3
      ref: v0.19.0      # ← 古いv0.10.0から更新
    components: [sesame, sesame_ble]

esp32:
  board: esp32-c3-devkitm-1
  framework:
    type: arduino

以降は各種キー・アドレスを秘密として設定

my-esp.yaml
sesame:
  - id: sesame1
    model: sesame_5
    address: !secret sesame1_bluetooth
    secret: !secret sesame1_secret
    public_key: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
    battery_pct:
      name: lock_battery_level
    lock:
      name: lock_upper
      id: lock_upper

運用上の注意

Clean Build を必ず実行。
.esphome/build.piolibdepsを消すか、GUIの「Clean build Files」

libsesame3btがキャッシュに残っていると、また古いコードを拾います。
libraries:libsesame3btを直書きしない(外部コンポーネントが依存を解決します)

platform: sesame_locklock.LOCK_SCHEMA系の記述は完全に除去。
同一ESP上で 他のBLEトラッカーと同居させると競合することがあるので、検証時はいったん外すのが安全。

まとめと直し方

壊れた理由:Arduino-ESP32 3.x でmbedTLS 3になり、
内部直叩きのCMAC自前実装が通らなくなった。

・外部コンポーネントを更新(例:v0.19.0)
-DCONFIG_MBEDTLS_CMAC_C-DUSE_FRAMEWORK_MBEDTLS_CMACbuild_flagsに追加
・旧スキーマplatform: sesame_lock / lock.LOCK_SCHEMAをやめて新スキーマへ
C・lean Buildでキャッシュを掃除

これでmbedTLS 3でもビルドが通るようになります。

最後に全体的なコードを記載します

myu-esp.yaml
esphome:
  name: sesame
  friendly_name: sesame
  platformio_options:
    build_flags:
      - -std=gnu++17 -Wall -Wextra
      - -DMBEDTLS_DEPRECATED_REMOVED
      - -DCONFIG_BT_NIMBLE_ROLE_BROADCASTER_DISABLED
      - -DCONFIG_BT_NIMBLE_ROLE_PERIPHERAL_DISABLED
      - -DCONFIG_BT_NIMBLE_MAX_CONNECTIONS=4
      - -DCONFIG_MBEDTLS_CMAC_C
      - -DUSE_FRAMEWORK_MBEDTLS_CMAC
    build_unflags:
      - -std=gnu++11
    lib_ldf_mode: deep

external_components:
  - source:
      type: git
      url: https://github.com/homy-newfs8/esphome-sesame3
      ref: v0.19.0
    components: [sesame, sesame_ble]

esp32:
  board: esp32-c3-devkitm-1
  framework:
    type: arduino

logger:

api:
  encryption:
    key: "xxxxxxxxxxxxx初期生成のものxxxxxxxxxxxxxxx"
ota:
  - platform: esphome
    password: "xxxxxxxxxxxxx初期生成のものxxxxxxxxxxxxxxx"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  manual_ip:
    static_ip: 192.168.***.*** #ESPに割り当てるIP
    gateway: 192.168.***.**
    subnet: 255.255.255.0
    dns1: 8.8.8.8
    dns2: ***.***.***.*** #dns2はなくても良い
  ap:
    ssid: "Sesame Fallback Hotspot"
    password: "xxx初期生成のものxxx"

captive_portal:

# 初回にBLEアドレス探索したいときだけ有効化
# sesame_ble:

sesame:
  - id: sesame1
    model: sesame_5
    address: !secret sesame1_bluetooth
    secret: !secret sesame1_secret
    public_key: "xxxxxxxxxxxxxxxxxxxxxxxxxxxx"
    battery_pct:
      name: lock_battery_level
    lock:
      name: lock_upper
      id: lock_upper

secrets.yaml
#Wi-Fi情報(SSIDとPW)
wifi_ssid: "SSID名"
wifi_password: "xxxxxxxxxxxx"
sesame1_bluetooth: "xx取得したMACアドレスxx"
sesame1_secret: "xxxxxxx取得したsecretkeyxxxxxx"

Discussion