Skip to content

Commit f02ba84

Browse files
authored
Merge pull request #255 from tamasan238/pr242
[JA] Added wolfTPM Appendix for build with bare-metal
2 parents 6fdb0ab + 665d59d commit f02ba84

1 file changed

Lines changed: 358 additions & 0 deletions

File tree

wolfTPM/src-ja/chapter02.md

Lines changed: 358 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -396,3 +396,361 @@ cd ..
396396
#### Windows上での実行
397397

398398
マシン上でのTPMの存在とその状態を確認する為には"tpm.msc"を実行してください。
399+
400+
### ベアメタル環境向けのビルド
401+
402+
wolfTPMは、OSが存在しないベアメタルの組み込み環境向けにもビルドできます。
403+
このセクションでは、wolfTPMをユーザのプロジェクトへ導入し、autotoolsやCMakeを使用せずにコンパイルする手順を解説します。
404+
405+
このセクションで示す手順は、ARM Cortex-MやRISC-V、UltraScale+/Versal、Microblazeのような一般的なマイコンボードに適用できます。
406+
407+
#### 準備
408+
409+
- wolfCryptのソースコード (wolfSSLリポジトリに含まれます)
410+
- wolfTPMのソースコード
411+
- SPIまたはI2Cで接続されたTPM 2.0チップ
412+
413+
#### ステップ1:プリプロセッサマクロの定義
414+
415+
ユーザのプロジェクトにおけるビルド設定やコンパイルコマンドに、以下のプリプロセッサマクロを追加します。
416+
417+
```
418+
WOLFTPM_USER_SETTINGS
419+
WOLFSSL_USER_SETTINGS
420+
```
421+
422+
これらのマクロを定義することで、wolfTPMとwolfSSLはautoconfが作成した`options.h`ではなく`user_settings.h`を参照するようになります。
423+
424+
425+
#### ステップ2:user_settings.hの作成
426+
427+
ユーザのプロジェクトに、wolfTPMとwolfSSLの構成オプションを記した`user_settings.h`を作成します。
428+
429+
詳細はwolfSSLリポジトリ内で提供しているリファレンスファイル[examples/configs/user_settings_wolftpm.h](https://github.com/wolfSSL/wolfssl/blob/master/examples/configs/user_settings_wolftpm.h)をご覧ください。
430+
431+
wolfTPM向けの`user_settings.h`のサンプルは次のとおりです。
432+
433+
434+
```h
435+
/* System */
436+
#define WOLFSSL_GENERAL_ALIGNMENT 4
437+
#define SINGLE_THREADED
438+
#define WOLFCRYPT_ONLY
439+
#define SIZEOF_LONG_LONG 8
440+
441+
/* Platform - bare metal */
442+
#define NO_FILESYSTEM
443+
#define NO_WRITEV
444+
#define NO_MAIN_DRIVER
445+
#define NO_DEV_RANDOM
446+
#define NO_ERROR_STRINGS
447+
#define NO_SIG_WRAPPER
448+
449+
/* wolfTPM required features */
450+
#define WOLF_CRYPTO_CB
451+
#define WOLFSSL_PUBLIC_MP
452+
#define WOLFSSL_AES_CFB
453+
#define HAVE_AES_DECRYPT
454+
455+
/* ECC options */
456+
#define HAVE_ECC
457+
#define ECC_TIMING_RESISTANT
458+
459+
/* RSA options */
460+
#undef NO_RSA
461+
#define WOLFSSL_KEY_GEN
462+
#define WC_RSA_BLINDING
463+
464+
/* Big math library */
465+
#define WOLFSSL_SP_MATH_ALL /* sp_int.c */
466+
#define WOLFSSL_SP_SMALL
467+
#define SP_INT_BITS 4096
468+
//#define SP_WORD_SIZE 32
469+
470+
/* SHA options */
471+
#define NO_SHA /* on by default */
472+
#define NO_SHA256 /* on by default */
473+
#define WOLFSSL_SHA512
474+
#define WOLFSSL_SHA384
475+
476+
/* Disable unneeded features to reduce footprint */
477+
#define NO_PKCS8
478+
#define NO_PKCS12
479+
#define NO_PWDBASED
480+
#define NO_DSA
481+
#define NO_DES3
482+
#define NO_RC4
483+
#define NO_PSK
484+
#define NO_MD4
485+
#define NO_MD5
486+
#define WOLFSSL_NO_SHAKE128
487+
#define WOLFSSL_NO_SHAKE256
488+
#define NO_DH
489+
490+
/* Other interesting size reduction options */
491+
#if 0
492+
#define RSA_LOW_MEM
493+
#define WOLFSSL_AES_SMALL_TABLES
494+
#define USE_SLOW_SHA
495+
#define USE_SLOW_SHA256
496+
#define USE_SLOW_SHA512
497+
#define NO_AES_192
498+
#endif
499+
500+
/* Custom random seed source - implement your own */
501+
#define HAVE_HASHDRBG
502+
#define CUSTOM_RAND_GENERATE_SEED my_rng_seed
503+
```
504+
505+
`CUSTOM_RAND_GENERATE_SEED`を使用する場合、ユーザは別途独自のRNGシード関数を定義する必要があります。
506+
507+
```c
508+
int my_rng_seed(byte* seed, word32 sz)
509+
{
510+
int rc;
511+
(void)os;
512+
/* enable parameter encryption for the RNG request */
513+
rc = wolfTPM2_SetAuthSession(&wolftpm_dev, 0, &wolftpm_session,
514+
(TPMA_SESSION_decrypt | TPMA_SESSION_encrypt |
515+
TPMA_SESSION_continueSession));
516+
if (rc == 0) {
517+
rc = wolfTPM2_GetRandom(&wolftpm_dev, seed, sz);
518+
}
519+
wolfTPM2_UnsetAuthSession(&wolftpm_dev, 0, &wolftpm_session);
520+
return rc;
521+
}
522+
```
523+
524+
#### ステップ3:インクルードパスの設定
525+
526+
ユーザのプロジェクトにて、以下のディレクトリをインクルードパスに追加します。
527+
528+
1. **wolfSSLルートディレクトリ** - 例:`/path/to/wolfssl`
529+
2. **wolfTPMルートディレクトリ** - 例:`/path/to/wolftpm`
530+
3. **ステップ2で作成した user_settings.h** - 必ず、コンパイラが辿れるように構成する必要があります。
531+
532+
コンパイラフラグの例を以下に示します。
533+
534+
```sh
535+
-I/path/to/wolfssl
536+
-I/path/to/wolftpm
537+
-I/path/to/your/project/include
538+
```
539+
540+
#### ステップ4:ソースファイルの追加
541+
542+
必要なソースファイルを、wolfSSL/wolfTPMリポジトリからユーザのプロジェクトに追加します。
543+
544+
545+
**wolfCryptソースファイル** (wolfTPMを使用するための最小構成):
546+
547+
```
548+
wolfssl/wolfcrypt/src/aes.c
549+
wolfssl/wolfcrypt/src/asn.c
550+
wolfssl/wolfcrypt/src/cryptocb.c
551+
wolfssl/wolfcrypt/src/ecc.c
552+
wolfssl/wolfcrypt/src/hash.c
553+
wolfssl/wolfcrypt/src/hmac.c
554+
wolfssl/wolfcrypt/src/random.c
555+
wolfssl/wolfcrypt/src/rsa.c
556+
wolfssl/wolfcrypt/src/sha.c
557+
wolfssl/wolfcrypt/src/sha256.c
558+
wolfssl/wolfcrypt/src/sha512.c
559+
wolfssl/wolfcrypt/src/sp_int.c
560+
wolfssl/wolfcrypt/src/wc_port.c
561+
wolfssl/wolfcrypt/src/wolfmath.c
562+
```
563+
564+
**wolfTPMソースファイル**
565+
566+
```
567+
wolftpm/src/tpm2.c
568+
wolftpm/src/tpm2_packet.c
569+
wolftpm/src/tpm2_tis.c
570+
wolftpm/src/tpm2_wrap.c
571+
wolftpm/src/tpm2_param_enc.c
572+
```
573+
574+
#### ステップ5:SPI HALコールバックの実装
575+
576+
wolfTPMはTPMチップと通信するために、単一のSPI送受信コールバックを使用します。
577+
ユーザは使用するハードウェアプラットフォームに対応するコールバック関数を別途実装する必要があります。
578+
579+
なお、wolfTPMリポジトリ内`hal/`ディレクトリにて、このコールバック関数の実装例をいくつか提供しています。
580+
ぜひお使いください。
581+
582+
- [hal/tpm_io_xilinx.c](https://github.com/wolfSSL/wolfTPM/blob/master/hal/tpm_io_xilinx.c) - Xilinx Microblaze
583+
- [hal/tpm_io_stm32.c](https://github.com/wolfSSL/wolfTPM/blob/master/hal/tpm_io_stm32.c) - STM32
584+
- [hal/tpm_io_infineon.c](https://github.com/wolfSSL/wolfTPM/blob/master/hal/tpm_io_infineon.c) - Infineon Tricore
585+
- [hal/tpm_io_microchip.c](https://github.com/wolfSSL/wolfTPM/blob/master/hal/tpm_io_microchip.c) - Microchip
586+
587+
##### 標準的な入出力コールバック
588+
589+
SPIコールバックは以下のように定義されます。
590+
591+
```c
592+
typedef int (*TPM2HalIoCb)(
593+
TPM2_CTX* ctx,
594+
const byte* txBuf, byte* rxBuf,
595+
word16 xferSz,
596+
void* userCtx
597+
);
598+
```
599+
600+
これに基づいて、以下のように実装します。
601+
602+
```c
603+
#include <wolftpm/tpm2.h>
604+
#include <wolftpm/tpm2_tis.h>
605+
606+
int TPM2_IoCb(TPM2_CTX* ctx,
607+
const byte* txBuf, byte* rxBuf, word16 xferSz,
608+
void* userCtx)
609+
{
610+
int ret = TPM_RC_FAILURE;
611+
612+
/* TODO: Assert SPI chip select */
613+
spi_cs_assert();
614+
615+
/* Perform SPI transfer - simultaneously send txBuf and receive to rxBuf */
616+
if (spi_transfer(txBuf, rxBuf, xferSz) == 0) {
617+
ret = TPM_RC_SUCCESS;
618+
}
619+
620+
/* TODO: De-assert SPI chip select */
621+
spi_cs_deassert();
622+
623+
(void)ctx;
624+
(void)userCtx;
625+
626+
return ret;
627+
}
628+
```
629+
630+
##### 応用的な入出力コールバック
631+
632+
さらなる制御を必要とするプラットフォームを使用する場合、`WOLFTPM_ADV_IO`を定義することで以下のようなコールバックを利用できます。
633+
634+
```c
635+
typedef int (*TPM2HalIoCb)(
636+
TPM2_CTX* ctx,
637+
INT32 isRead, UINT32 addr,
638+
BYTE* xferBuf, UINT16 xferSz,
639+
void* userCtx
640+
);
641+
```
642+
643+
これにより、レジスタアドレスへのアクセスや、読み込み・書き込み操作を分ける必要のあるプラットフォーム向けの読み書き方向の提示(`isRead`)ができるようになります。
644+
645+
#### ステップ6:wolfTPMの初期化と使用
646+
647+
ここまでの手順を終えると、以下のようにしてwolfTPMを使用してTPMとの通信を行えます。
648+
649+
```c
650+
#include <wolftpm/tpm2_wrap.h>
651+
652+
int main(void)
653+
{
654+
int rc;
655+
WOLFTPM2_DEV dev;
656+
657+
/* Initialize wolfTPM */
658+
rc = wolfTPM2_Init(&dev, TPM2_IoCb, NULL);
659+
if (rc != TPM_RC_SUCCESS) {
660+
/* Handle error */
661+
return rc;
662+
}
663+
664+
/* Get TPM capabilities */
665+
WOLFTPM2_CAPS caps;
666+
rc = wolfTPM2_GetCapabilities(&dev, &caps);
667+
if (rc == TPM_RC_SUCCESS) {
668+
/* Use TPM ... */
669+
}
670+
671+
/* Cleanup */
672+
wolfTPM2_Cleanup(&dev);
673+
674+
return 0;
675+
}
676+
```
677+
678+
#### 任意のビルド構成オプション
679+
680+
##### メモリ使用量の削減
681+
682+
制約の厳しい環境では、`user_settings.h`に以下のオプションを追加することをご検討ください。
683+
684+
```c
685+
/* Reduce stack usage */
686+
#define WOLFTPM_SMALL_STACK
687+
688+
/* Disable wrapper layer if using native API only */
689+
#define WOLFTPM2_NO_WRAPPER
690+
691+
/* Use smaller RSA key sizes only */
692+
#define MAX_RSA_BITS 2048
693+
```
694+
695+
##### TPMチップタイプの選択
696+
697+
コンパイル時にTPMチップのタイプが判明している場合、以下のフラグを使用できます。
698+
699+
```c
700+
/* For Infineon */
701+
#define WOLFTPM_SLB9670
702+
#define WOLFTPM_SLB9672
703+
#define WOLFTPM_SLB9673
704+
705+
/* For ST ST33 */
706+
#define WOLFTPM_ST33
707+
708+
/* For Nuvoton */
709+
#define WOLFTPM_NUVOTON
710+
711+
/* For Microchip ATTPM20 */
712+
#define WOLFTPM_MICROCHIP
713+
```
714+
715+
指定されていない場合、wolfTPMはチップタイプを自動で検出します。
716+
この機能はデフォルトで定義されている`WOLFTPM_AUTODETECT`により実行されます。
717+
718+
##### I2C対応
719+
720+
TPMチップがSPIではなくI2Cで接続されている場合、以下のオプションを追加してください。
721+
722+
```c
723+
#define WOLFTPM_I2C
724+
#define WOLFTPM_ADV_IO
725+
```
726+
727+
I2C通信で使用する応用的な入出力コールバックは別途実装する必要があります。
728+
729+
#### 暗号鍵ストレージ
730+
731+
TPMチップにより、メインメモリから隔離された暗号鍵のための安全な記憶域を使用できます。
732+
保存された鍵情報が平文でTPMから外に出ることはありません。
733+
734+
- `TPM2_CreatePrimary`を使用して鍵を作成すると、TPM内で保管されます。
735+
- `TPM2_Create`を使用して鍵を作成すると、NVRAMに保管できるよう暗号化されたものが返却されます。これは`TPM2_Load`を使用することで再びTPMに読み込むことが可能です。
736+
- `TPM2_EvictControl`を使用することで、鍵を永続的にTPMのNVRAMに格納できます。
737+
738+
この分離により、万一メインプロセッサのメモリが侵害されても暗号鍵は保護されます。
739+
740+
#### トラブルシューティング
741+
742+
##### SPI通信に関する問題
743+
744+
1. SPIのクロック極性と周期を確認します。CPOL=0, CPHA=0 のような値です。
745+
2. SPIのクロック速度を確認します。まずは1〜10MHzのようなゆっくりとした速度でお試しになることをおすすめします。
746+
3. 送受信フローでチップ選択が行われていることを確認します。
747+
4. いくつかのTPMでは、SPI操作の中に待機ステートを含めることが求められます。これはMSBに到達するまでのすべてのデータを読み込むために必要な場合があります。その場合、`WOLFTPM_CHECK_WAIT_STATE`を有効化してください。
748+
5. `#define DEBUG_WOLFTPM`(標準)や、`WOLFTPM_DEBUG_VERBOSE`(詳細)、`WOLFTPM_DEBUG_IO`(SPI/I2C関連)を有効化し、デバッグ出力を確認します。
749+
750+
##### ビルドエラーが発生する場合
751+
752+
1. `WOLFSSL_USER_SETTINGS`および`WOLFTPM_USER_SETTINGS`が有効化されていることを確認します。
753+
2. インクルードパスが正しく設定されていることを確認します。
754+
3. 必要なソースファイルのすべてが用意されていることを確認します。
755+
756+
詳しい手順は本セクション「ベアメタル環境向けのビルド」ステップ1〜6をご参照ください。

0 commit comments

Comments
 (0)