hiro99ma blog

何か技術的なこと

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 ではダメらしい。
-Ipwd/.." は↑に書いた 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 pathMakefile をローカルで編集して -lsecp256k1 を外し Mbed TLS のライブラリだけにしたのだがリンクエラーになった。

シュノア署名は、まあわかる。 あれを実装したライブラリがあるのか私は知らない。
しかし ecdsa は MbedTLS にもあるのだからそっちを使えばいいじゃないか。

私はようやく ./configure でチェックされていたのが sha256.hsha512.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 社がそれを考えてないとは思えないしなぁ。

要研究ということで。

< Top page