clang: Mbed TLSとPSA
2025/02/16
はじめに
Mbed TLS をビルドしよう。
WSL2 を使う。
ビルド
Mbed TLS は組み込みソフトウェアでよく使われる crypto ライブラリの1つである。 最近組み込んでいない私だが、以前はよくお世話になった。
これを書いている時点での最新 release は v3.6.2 だったのでそれを使う。
手順に書いてある通りなのだが、git submodule
しないと make
に失敗する。
make
に失敗したときに指示が出るのでその通りにやれば良いだけだ。
クロスコンパイルの仕方も書いてあるので Mbed TLS らしい。
$ git clone https://github.com/Mbed-TLS/mbedtls.git
$ cd mbedtls
$ git checkout -b mbedtls-3.6.2 refs/tags/mbedtls-3.6.2
$ git submodule update --init
$ make
$ ls library/*.a
library/libmbedcrypto.a library/libmbedtls.a library/libmbedx509.a
v3.6.2 のビルドに必要なツールはこちらに書いてある。 私の環境では既にインストールされていたのか何も言われなかったので特に言えることはない。
ヘッダファイルで設定を変更することもできる。
make install
のインストール先は $DESTDIR
で /usr/local
だ。
make
の引数にすると変更できるのか。知らなかった。。。
ビルドした実行ファイルもインストールされるようだ。
サンプルコードはほしいけど実行ファイルは個人的にはいらないんだけどね。73ファイルもあるし。
$ make DESTDIR=$HOME/.local
$ mbedtls_hello
MD5('Hello, world!') = 6cd3556deb0da54bca060b4c39479839
PSA
最近の Mbed TLS といえば PSA 対応だろう、と勝手に思っている。
ML でも v4.0 のリリースタイムラインどうとか流れてたし。
まだリリースは先のことだが PSA の方がデフォルトになるとか書いてあった。
ただ残念な感じがするのは General application layout によると
リソース解放に mbedtls_psa_crypto_free()
を呼び出すそうだ。
確かにサンプル もそれで終わっている。
そして valgrind
でも psa_crypto_init()
だけ呼んで mbedtls_psa_crypto_free()
を呼ばないとリークしていた。
恐るべし。。。
ライブラリ管理の API を見ても PSA には終わりとして呼ぶ関数は定義されていないようだ。
完全にライブラリ非依存というのは無理そうだ。
まあ、それならそれでプリプロセスとポストプロセスをライブラリごとに実装して#ifdef
などしていけばよいか。
おわりに
ちょっとだけ Mbed TLS で PSA の関数を使ってみた。
初期化だけなので使ったというのもおこがましいが、include とリンクが解決できることが確認できればあとは呼び出すだけなのでよいのだ。
おまけ
libwally-core で Mbed TLS を使う
せっかくなので libwally-core で Mbed TLS を使うようにしてみたい。
configure options にあるよう --enable-mbed-tls
を指定すると以下の2ファイルが必要というか include される。
#include <sdkconfig.h>
#include <soc/soc_caps.h>
Mbed TLS は別に組み込みソフトウェア専用というわけではないので PC Linux でも動作するのだがこの 2ファイルはない。
なくても困らないので空ファイルを適当な場所に作った。
前回のビルド では --enable-standard-secp --with-system-secp256k1
をつけてオリジナルの libsecp256k1 を使うようにしていたが、
Mbed TLS を使うことだし気にしないことにした。
Mbed TLS をシステムにインストールしていないため CFLAGS
でパスを教えないと失敗した。
--includedir
ではダメらしい。
-I
pwd/.."
は↑に書いた 2つの空ヘッダファイル用である。
LDFLAGS
はいらなかったんじゃないかという気がする。まあついでだ。
$ ./configure --enable-minimal --disable-elements --enable-static --disable-shared --disable-elements-abi --enable-mbed-tls --prefix=$HOME/.local CFLAGS="-I${HOME}/.local/include -I`pwd`/.." LDFLAGS="-L${HOME}/.local/lib -lmbedtls -lmbedx509 -lmbedcrypto"
......
checking for mbedtls/sha256.h... yes
checking for mbedtls/sha512.h... yes
......
$ make
以前作った P2TR key path の Makefile
をローカルで編集して -lsecp256k1
を外し Mbed TLS のライブラリだけにしたのだがリンクエラーになった。
- undefined reference to `secp256k1_context_create’
- undefined reference to `secp256k1_ecdsa_verify’
- …
シュノア署名は、まあわかる。
あれを実装したライブラリがあるのか私は知らない。
しかし ecdsa は MbedTLS にもあるのだからそっちを使えばいいじゃないか。
私はようやく ./configure
でチェックされていたのが sha256.h
と sha512.h
だけだったことを思い出した。
もしかして、その 2つしか Mbed TLS の関数を使ってない・・・?
Makefile
に -lsecp256k1
を追加したところエラーは出なくなった。
まあ、それはそうだよね。
しかしここでも発見があった。
github.com/BlockstreamResearch/secp256k1-zkp
のライブラリ名は libsecp256k1
とオリジナルと同じみたいで install すると上書きされたようなのだ。
えー、zkp って名前に付くくらいだしゼロ知識証明を前面に押し出して別の名前にするんじゃないの??
中身を見てないけどオリジナル+αならよいと思ったのかもしれないが、区別が付かない私からすると別の名前であってほしかった。
まあいい。
それは、まあいいよ。
問題は libsecp256k1
が必要という方にある。
sha512
は使わないかもしれないが sha256
は使っているはずだ。
libsecp256k1-zkp
も内部で使用している sha256
を公開すれば MbedTLS を使わなくてもよかったのでは。
sha512
を実装するとかね。
Blockstream社は Jade というハードウェアウォレットを販売していて、そこで使っているソースコードも公開してる。
その Jade でも libwally-core は使われている。
ESP32 を使ったハードウェアなのだが、P2TR は対応してたっけ?
Mbed TLS で大半の Bitcoin 実装を作ることは可能だ。
シュノア署名はなかっただろうが、 P2WPKH や P2WSH までは実装したことがあるのでできるはずだ。
となると、どちらかというと Mbed TLS を使った方が組み込みソフトウェアとしては無駄な実装になり得る?
しかし Blockstream 社がそれを考えてないとは思えないしなぁ。
要研究ということで。