こんにちは、
最近、SDK 25.12 にアップデートしたところ、TLS 復号化率が半分に低下していることに気付きました。
mbedTLS v3.x は、 fsl_hashcryptハードウェア機能を使用して高速化されなくなりました。
以下は、以前の SDK 25.09 を使用してmbedtls_ssl_readを呼び出すコールスタックです。ご覧のとおり、最終的にはHASHCRYPT_AES_EncryptEcbが使用されます。
hashcrypt_aes_one_block_aligned() at fsl_hashcrypt.c:437
hashcrypt_aes_one_block() at fsl_hashcrypt.c:581
HASHCRYPT_AES_EncryptEcb() at fsl_hashcrypt.c:1,284
mbedtls_internal_aes_encrypt() at aes_alt.c:1,959
mbedtls_aes_crypt_ecb() at aes_alt.c:1,323
aes_crypt_ecb_wrap() at cipher_wrap.c:114
mbedtls_cipher_update() at cipher.c:521
mbedtls_gcm_update() at gcm.c:358
mbedtls_gcm_crypt_and_tag() at gcm.c:456
mbedtls_gcm_auth_decrypt() at gcm.c:491
mbedtls_cipher_aead_decrypt() at cipher.c:1,407
mbedtls_cipher_auth_decrypt_ext() at cipher.c:1,613
mbedtls_ssl_decrypt_buf() at ssl_msg.c:1,242
ssl_prepare_record_content() at ssl_msg.c:3,667
ssl_get_next_record() at ssl_msg.c:4,551
mbedtls_ssl_read_record() at ssl_msg.c:3,817
mbedtls_ssl_read() at ssl_msg.c:5,237
<...more frames...>MBEDTLS_USE_PSA_CRYPTOが定義された SDK 25.12 のコールスタックを以下に示します。このバージョンでは、 mbedtls_internal_aes_encryptはすべて C コードで、ハードウェアアクセラレーションは使用されていません。
mbedtls_internal_aes_encrypt() at aes.c:894
mbedtls_aes_crypt_ecb() at aes.c:1,062
aes_crypt_ecb_wrap() at cipher_wrap.c:166
mbedtls_cipher_update() at cipher.c:611
gcm_mask() at gcm.c:546
mbedtls_gcm_update() at gcm.c:641
mbedtls_gcm_crypt_and_tag() at gcm.c:726
mbedtls_gcm_auth_decrypt() at gcm.c:753
mbedtls_psa_aead_decrypt() at psa_crypto_aead.c:270
psa_driver_wrapper_aead_decrypt() at psa_crypto_driver_wrappers.h:4,114
psa_aead_decrypt() at psa_crypto.c:5,023
mbedtls_ssl_decrypt_buf() at ssl_msg.c:1,625
ssl_prepare_record_content() at ssl_msg.c:4,093
ssl_get_next_record() at ssl_msg.c:5,068
mbedtls_ssl_read_record() at ssl_msg.c:4,323
mbedtls_ssl_read() at ssl_msg.c:5,983
<...more frames...>以下は、 MBEDTLS_USE_PSA_CRYPTOが定義されていない SDK 25.12 のコールスタックです。このバージョンでは、 mbedtls_internal_aes_encryptはすべて C コードであり、HW アクセラレーションはなく、PSA は使用されません。
mbedtls_internal_aes_encrypt() at aes.c:899
mbedtls_aes_crypt_ecb() at aes.c:1,062
aes_crypt_ecb_wrap() at cipher_wrap.c:166
mbedtls_cipher_update() at cipher.c:611
gcm_mask() at gcm.c:546
mbedtls_gcm_update() at gcm.c:628
mbedtls_gcm_crypt_and_tag() at gcm.c:726
mbedtls_gcm_auth_decrypt() at gcm.c:753
mbedtls_cipher_aead_decrypt() at cipher.c:1,528
mbedtls_cipher_auth_decrypt_ext() at cipher.c:1,674
mbedtls_ssl_decrypt_buf() at ssl_msg.c:1,639
ssl_prepare_record_content() at ssl_msg.c:4,093
ssl_get_next_record() at ssl_msg.c:5,068
mbedtls_ssl_read_record() at ssl_msg.c:4,323
mbedtls_ssl_read() at ssl_msg.c:5,983
<...more frames...>RT685 HASHCRYPT ハードウェア アクセラレーションを mbedTLS に復元する予定はありますか?特定の PSA Crypto ドライバーが実装されていないようです。
よろしくお願いします。
こんにちは、エドウィン。
EVKで問題を再現しました。2つのサンプルに、200回の反復処理のループを追加して修正しました。 mbedtls_gcm_self_test RTC クロックを使用して全体の実行時間を計測しました。
evkmimxrt685_mbedtls_selftest_cm33 SDK 25.09からテストを実行しました 1087ミリ秒 このコールスタックでは:
HASHCRYPT_AES_EncryptEcb() at fsl_hashcrypt.c:1,260
mbedtls_internal_aes_encrypt() at aes_alt.c:1,959
mbedtls_aes_crypt_ecb() at aes_alt.c:1,323
aes_crypt_ecb_wrap() at cipher_wrap.c:114
mbedtls_cipher_update() at cipher.c:521
mbedtls_gcm_starts() at gcm.c:294
mbedtls_gcm_crypt_and_tag() at gcm.c:452
mbedtls_gcm_self_test() at gcm.c:826evkmimxrt685_mbedtls3x_psatest_cm33 SDK 25.12からテストを実行しました 8990ミリ秒 このコールスタックでは:
mbedtls_internal_aes_encrypt() at aes.c:896
mbedtls_aes_crypt_ecb() at aes.c:1,062
aes_crypt_ecb_wrap() at cipher_wrap.c:166
mbedtls_cipher_update() at cipher.c:611
mbedtls_gcm_starts() at gcm.c:441
mbedtls_gcm_crypt_and_tag() at gcm.c:718
mbedtls_gcm_self_test() at gcm.c:1,075
evkmimxrt685_mbedtls3x_psatest_cm33 SDK 25.12以降 MBEDTLS_PSA_ACCEL_KEY_TYPE_AES 定義されたテストを実行した 8744ミリ秒 このコールスタックでは:
HASHCRYPT_AES_EncryptEcb() at fsl_hashcrypt.c:1,255
hashcrypt_cipher_encrypt() at mcux_psa_hashcrypt_common_cipher.c:187
psa_driver_wrapper_cipher_encrypt() at psa_crypto_driver_wrappers.h:2,353
psa_cipher_encrypt() at psa_crypto.c:4,766
mbedtls_block_cipher_encrypt() at block_cipher.c:177
mbedtls_gcm_starts() at gcm.c:439
mbedtls_gcm_crypt_and_tag() at gcm.c:718
mbedtls_gcm_self_test() at gcm.c:1,075例の変更点の要点は次のとおりです。
BOARD_InitHardware();
test_rtc_init();
psa_crypto_init();
uint64_t ms_start = test_rtc_get_msecs();
for (int i = 0; i < 200; ++i)
{
PRINTF("test iteration %d\r\n", i+1);
mbedtls_gcm_self_test(0);
}
uint64_t ms_end = test_rtc_get_msecs();
PRINTF("test time = %ums\r\n", (unsigned)(ms_end - ms_start));...ここで、 test_rtc_get_msecs は、1 秒未満の精度を使用して現在の RTC 時刻を返します。
ご覧のとおり、新しい SDK で GCM/AES を暗号化すると、速度が約 8 倍低下します。
ご希望であれば、修正したサンプルを添付することもできます。
よろしくお願いいたします。
アミルカル
こんにちは@hrc-amilcar 、
この質問にご辛抱いただきありがとうございます。社内チームからの返答を受け取りましたので、以下をご覧ください。
コールスタックから、従来の mbedtls_xxx 暗号 API を使用していることがわかります。実際、HW アクセラレーションではありません。mbedTLS3.xCrypto 用の新しい API が導入されました。これは PSA です。mbedtls/docs/psa-transition.md は v3.6.5 · Mbed-TLS/mbedtls · GitHub で高速化されています。レガシー暗号 API は MbedTLS4.x でさらに削除されます。
RT600 用の SDK で psa_crypto_examples を確認したところ、 PSA_CRYPTO_DRIVER_HASHCRYPT が定義されているため、暗号ドライバー ラッパーが暗号計算を HW にオフロードできるようになり、HASHCRYPT HW アクセラレーションがデフォルトで有効になっています。一方、MbedTLS3.x+ はより複雑で、PSA API 仕様に準拠しているため、一部のユースケースでは実際にパフォーマンスが低下する可能性があります。TLS の場合、この IP は bignum アクセラレーションのみをサポートし、HW IP がアルゴリズム全体を実装することを期待する PSA API との互換性があまりないため、むしろ非対称暗号化 (CASPER HW IP) がパフォーマンスのボトルネックになると予想されます。少なくとも一部の ECC 操作 (署名、検証) を高速化するために最善を尽くしましたが、ECDHE キー交換中の keygen などの他の操作では速度が低下する可能性があります。
ここで、パフォーマンス測定に PSA API を使用して、PSA_CRYPTO_DRIVER_HASHCRYPT が定義され、コール スタックがそれを使用していることを確認できるとよいでしょう。参考までに: Hashcrypt は AES-GCM アクセラレーションをネイティブに提供していないため、HW IP の実際のメリットを確認するには、AES-CBC または AES-CTR をベンチマークすることをお勧めします。
BR、
エドウィン。
こんにちは@hrc-amilcar 、
mbedTLS 2.x (PSA なし) から mbedTLS 3.x (PSA あり) に移行すると、次の理由によりパフォーマンスが低下する可能性があります。
PSAドライバインターフェースはまだ部分的にしか実装されていません。そのため、ドライバ作成に必要な成果物や、ドライバをMbed TLSに統合する方法は、高速化対象となる操作によって異なります。( https://mcuxpresso.nxp.com/mcuxsdk/latest/html/middleware/mbedtls3x/docs/psa-driver-example-and-guid...
現時点では、2.xから3.xへの適切な移行方法に関するガイドラインに従うことをお勧めしています: Mbed TLS 2.xからMbed TLS 3.0への移行 — MCUXpresso SDKドキュメント
PSA APIへの適切な移行ガイド: PSA APIへの移行 - MCUXpresso SDKドキュメント
ご不便をおかけして申し訳ございません。
BR、
エドウィン。
こんにちは@hrc-amilcar 、
SDK をアップデートした後に何か変更を加えましたか?SDK のサンプルコードでも同様の現象が見られますか?スタンドアロン IDE を使用していますか、それとも VS Code 拡張機能を使用していますか?
BR、
エドウィン。
HASHCRYPT_AES_EncryptEcb() at fsl_hashcrypt.c:1,255
hashcrypt_cipher_encrypt() at mcux_psa_hashcrypt_common_cipher.c:203
psa_driver_wrapper_cipher_encrypt() at psa_crypto_driver_wrappers.h:2,353
psa_cipher_encrypt() at psa_crypto.c:4,766
mbedtls_block_cipher_encrypt() at block_cipher.c:177
gcm_mask() at gcm.c:543
mbedtls_gcm_update() at gcm.c:628
mbedtls_gcm_crypt_and_tag() at gcm.c:726
mbedtls_gcm_auth_decrypt() at gcm.c:753
mbedtls_psa_aead_decrypt() at psa_crypto_aead.c:270
psa_driver_wrapper_aead_decrypt() at psa_crypto_driver_wrappers.h:4,114
psa_aead_decrypt() at psa_crypto.c:5,023
mbedtls_ssl_decrypt_buf() at ssl_msg.c:1,625
ssl_prepare_record_content() at ssl_msg.c:4,093
ssl_get_next_record() at ssl_msg.c:5,068
mbedtls_ssl_read_record() at ssl_msg.c:4,323
mbedtls_ssl_read() at ssl_msg.c:5,983
<...more frames...>こんにちは@EdwinHz 、
コードをステップ実行しているときに、 gcm 操作を高速化するために、おそらくMBEDTLS_BLOCK_CIPHER_C を定義する必要があることに気付きました。
ヘッダーmbedtls3x/include/mbedtls/config_adjust_legacy_crypto.hがこれに関係しているようですが、何らかの理由でそのマクロが定義されません。
他人の利益のために...
mbedTLS 3.xのmbedtls_xorは、一度に4バイトのデータをループして呼び出しているようです。 mbedtls_get_unaligned_uint32 そして mbedtls_put_unaligned_uint32 どちらも単一の uint32 に対して memcpy を使用します。
mbedTLS の作者たちは、一度に 4 バイトの XOR ブロックを計算する (剰余ループを使用) ことでパフォーマンスの向上を試みていることは承知していますが、memcpy の完全な呼び出しによって、実際にはコードの速度が低下しています。
逆アセンブリを調査した結果、プロジェクトが -fno-builtin でコンパイルされており、小さな memcpy がコンパイラによってインライン化されないことが判明しました。
このオプションを削除すると、AES-GCM 操作に使用されていない HASHCRYPT ハードウェアのパフォーマンス損失の多くが回復しました。SO、私が投稿した例では、実行時間が 8600 ミリ秒から 2100 ミリ秒に短縮されました。mbedTLS 2.x + ksdk alt (1087 ミリ秒) のレベルには達していません。しかし、復元されたパフォーマンスは十分良好です。
-アミルカル