2017/06/14

[mbedtls]keypairはスレッド間で共用するものではない

数日前、mbedTLSの楕円曲線署名と検証は排他した方が良いのかもしれん、という記事を書いた。
(実は、こそっと追記した。)

http://hiro99ma.blogspot.com/2017/06/mbedtls.html


しかし、mbedTLSの設定に MBEDTLS_THREADING_CやMBEDTLS_THREADING_PTHREADがあるので、少なくともLinuxで両オプションを有効にしていたら大丈夫で、自分のコーディングがよろしくないんじゃなかろうか、という感触が少なからずあった。
少なからずというか、今までの経験上、よく使われているライブラリで結果が変だったときは、だいたい自分の書き方が悪いときだったというだけだが。

Thread Safety and Multi Threading: concurrency issues - Knowledge Base - mbed TLS (Previously PolarSSL)


モヤモヤしていたので見直しを行ったところ、mbedtls_ecp_keypairを共用している(自分が)ことが分かった。
ただ、mbedtls_ecp_group_load()でgrpメンバを設定して使う、という使い方しかしていないので、グローバル変数でもよいだろうと思っていたのだ。

が・・・実装しているうちに「署名の検証ってmbedtls_ecdsa_read_signature()にmbedtls_ecp_keypairをmbedtls_ecdsa_contextでキャストすれば使えるやん、ということに気付いてしまった。

//mbedtls/ecdsa.h
typedef mbedtls_ecp_keypair mbedtls_ecdsa_context;

そう、楕円曲線の検証だけgrpではなくkeypair全体を使っていたのだ。
そして、mbedtls_ecp_keypair構造体はメンバとして秘密鍵や公開鍵を持つようになっている。
実装までは確認していないが、署名の検証にそれらが使われているのは当然だろう。


いくらスレッドセーフだったとしても、書き換える対象の変数を共用していては意味が無い、というわけだ。


では、mbedtls_ecp_groupだったら共用させても大丈夫かなー、と思ったのだが、mbedTLSのインターフェースとしてはconst付きとconstなしがある。

さすがにconstなしのところを共用するのは同じ事態を引き起こすことになるだろうから、共用は止めて毎回スタックで設定するようにした。


共用で気にしているのは、mbedtls_entropy_contextとmbedtls_ctr_drbg_contextだ。
RNGが使いたかったし、毎回設定するようなものでもないと思ったのでグローバル変数として持っている。
mbedTLSのサイトでは、EntropyとCTR-DRBGはリストに載っているのだが、これは何のリストだ?
init/free()があって、メインスレッドから呼びなさい、と言っているようだが・・・。

mutexの初期化と解放をそこで行っているからメインスレッドから呼べ、ということかな?
だったら、他のところは別スレッドから呼んでもよいということになろう。

読む解くのが苦手ですわ。。。

0 件のコメント:

コメントを投稿

コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。