Chapter 08
暗号アクセラレータと乱数生成器
この章がなぜ必要なのか——乱数の質が、全部の土台だから.
どんなに強い暗号を使っても、鍵が予測できるなら意味がない。 TLS のセッション鍵も、機器の秘密鍵も、ノンス(1 回きりで使い捨てる値)も、 IV(暗号化のたびに変える初期値)も、すべて乱数から作られる。
乱数生成器は、セキュリティにおける単一障害点である。 そして組み込みでは、ここが驚くほど頻繁に壊れている。
この章で使う既出の用語(定義は各リンク先). 物理攻撃(04 章 6 節)、署名検証(04 章 4 節)、RSA-2048(05 章 3 節)、経年劣化(06 章 3 節)、起動時間(06 章 3 節)、Crypto(07 章 4 節)、Secure(07 章 3 節)、TrustZone(07 章 2 節)、サイドチャネル(07 章 8 節)
1. 乱数の質が壊れた実例
| 事例 | 何が起きたか |
|---|---|
| Debian OpenSSL 事件(2008) | 乱数生成のコードを誤って削除。2 年間、生成された鍵が 32768 通りしかなかった |
| 組み込み機器の RSA 鍵の共通因数(2012 の大規模調査) | インターネット上の TLS/SSH 鍵を収集したところ、多数の機器が素因数を共有していた。起動直後のエントロピー不足が原因 |
| Android の SecureRandom 欠陥(2013) | 初期化の不備で、Bitcoin ウォレットの秘密鍵が予測可能に |
| ゲーム機・組み込み機器の署名検証 | ECDSA のノンスを固定・再利用したため、署名 2 つから秘密鍵が計算された |
共通しているのは「エントロピー不足」である.
エントロピーとは、外から予測できない無秩序さの量のことで、乱数の「種」になる。 種が足りないまま乱数を作ると、出力が乱数らしく見えても、 実際には少数のパターンしか出ていない——上の事例はすべてこれである。
特に組み込みで危険なのが起動直後である。
- マウスもキーボードもない
- ディスク I/O のタイミングもない
- ネットワークもまだ繋がっていない
- 時計すら合っていない
PC やサーバでエントロピー源として使われるものが、何もない。 だからハードウェアの TRNG が必須になる。
2. TRNG と DRBG — 2 段構成
| TRNG(真性乱数) | DRBG(決定的乱数) | |
|---|---|---|
| 元 | 物理現象 | シード + アルゴリズム |
| 速度 | 遅い | 速い |
| 予測可能性 | 予測不能 | シードが分かれば完全に予測できる |
| 用途 | シード生成、長期鍵 | セッション鍵、ノンス、IV など大量に使うもの |
「DRBG があるから TRNG は要らない」は誤りである.
DRBG はシードを増幅するだけであり、エントロピーを作り出さない。 シードが 32 ビットの予測可能な値なら、出力も 32 ビットの探索で破られる。
TRNG が本物のエントロピーを供給しない限り、DRBG は無意味である。
3. 関連する標準
| 標準 | 内容 |
|---|---|
| NIST SP 800-90A | DRBG の仕様(Hash_DRBG / HMAC_DRBG / CTR_DRBG) |
| NIST SP 800-90B | エントロピー源の評価方法。min-entropy の推定、健全性テスト |
| NIST SP 800-90C | RBG(乱数ビット生成器)の構成方法 |
| AIS 31(ドイツ BSI) | 乱数生成器の評価クラス(PTG.1〜PTG.3、DRG.1〜DRG.4) |
| FIPS 140-3 | 暗号モジュール全体の認証。上記を含む |
データシートで確認すべきこと.
- 「NIST SP 800-90B 準拠」または「AIS 31 PTG.2/PTG.3 準拠」と書かれているか
- エントロピーレート(1 ビットあたりの min-entropy)はいくつか
- オンライン健全性テストを持っているか
- 起動時のテスト(power-on self test)があるか
「TRNG 搭載」とだけ書かれていて、これらの記載がない場合は要注意である。 単なる LFSR や、ADC のノイズを読んだだけの実装も存在する。
乱数の品質を見る
エントロピー源の品質を変えて、生成される鍵空間がどう変わるかを確かめられる。
4. オンライン健全性テスト
TRNG は故障する。経年劣化、温度、電源ノイズ、そして意図的な攻撃によって。
| 攻撃 | 内容 |
|---|---|
| 周波数注入攻撃 | 外部から特定周波数の信号を注入し、発振器を同期させて出力を偏らせる |
| 温度攻撃 | 極端な温度でノイズ源の特性を変える |
| 電源攻撃 | 電源電圧を操作してエントロピーを下げる |
だから常時テストが必要になる。
| テスト | 内容 |
|---|---|
| 繰り返しカウントテスト (Repetition Count) | 同じ値が連続で出続けたら異常 |
| 適応比率テスト (Adaptive Proportion) | ある窓の中で、特定の値の出現率が高すぎたら異常 |
| 起動時テスト | 電源投入時に既知のテストを実行する |
これらは NIST SP 800-90B で規定されている。 異常を検出したら、乱数の供給を止めるかアラートを上げる設計にする。
ソフトウェア側でも、最低限の防御をしておくこと.
/* 悪い例: エラーを無視している */ uint8_t key[32]; hal_rng_read(key, 32); /* 戻り値を見ていない */ /* 良い例 */ uint8_t key[32]; if (hal_rng_read(key, 32) != HAL_OK) { /* ★ 乱数が取れなかった。鍵を作ってはいけない */ enter_safe_state(); } /* さらに、全部ゼロ・全部 FF などの明らかな異常値を弾く */ if (is_all_same(key, 32)) { enter_safe_state(); }「乱数生成に失敗したら止まる」設計にすること。 エラーを無視して 0 で埋まった鍵を使う、という事故が実際に起きている。
5. 暗号アクセラレータ
何を持っているか
| 種別 | 典型的な内容 | 効果 |
|---|---|---|
| 対称暗号 | AES-128/192/256(ECB/CBC/CTR/GCM/XTS/CCM) | 数十〜数百倍高速 |
| ハッシュ | SHA-1/224/256/384/512、SHA-3、HMAC | 数十倍高速 |
| 公開鍵演算 | モジュラ演算器、ECC 点演算、RSA | 数十〜数百倍高速 |
| 乱数 | TRNG + DRBG | 必須 |
| その他 | CRC、DES/3DES(レガシー)、ChaCha20-Poly1305 | — |
速度の目安
ハードウェアがあるかないかで、桁が違う。
| 演算 | ソフトウェア(Cortex-M4 @100 MHz) | ハードウェア |
|---|---|---|
| AES-128 暗号化(1 KB) | 約 200〜400 µs | 約 5〜20 µs |
| SHA-256(1 KB) | 約 100〜200 µs | 約 5〜20 µs |
| ECDSA P-256 署名検証 | 数十〜数百 ms | 数 ms〜数十 ms |
| RSA-2048 署名検証 | 約 10〜30 ms | 約 1〜5 ms |
| RSA-2048 署名生成 | 数百 ms〜数秒 | 数十 ms |
公開鍵演算の差が決定的である.
ECDSA P-256 の署名検証がソフトウェアで 200 ms かかると——
- セキュアブートが 200 ms 遅くなる(多段なら数倍)
- TLS ハンドシェイクが数百 ms 遅くなる
- 電池駆動ならその分の電力を消費する
起動時間や電池寿命の要件が厳しい製品では、 公開鍵アクセラレータ(PKA)の有無が SoC 選定を決めることがある。
アクセラレータの効果を見る
処理内容とクロックを変えて、ソフトウェア/ハードウェアの差を確かめられる。
各社の名称
| ベンダ | 対称・ハッシュ | 公開鍵 | 章 |
|---|---|---|---|
| ST | AES / SAES、HASH | PKA | 18 |
| NXP | DCP、HASHCRYPT、CAAM(i.MX) | CASPER(LPC55)、CAAM の PKHA | 19 |
| Espressif | AES、SHA | RSA アクセラレータ、ECC アクセラレータ(品種による) | 20 |
| Nordic | CryptoCell-310/312、CRACEN(nRF54L) | 同左に含む | 21 |
| Silicon Labs | Secure Element / Secure Engine | 同左に含む | 21 |
| Renesas | SCE(Secure Crypto Engine)、RSIP、TSIP(RX) | 同左に含む | 21 |
| Microchip | 品種による(CRYA など) | 外付け ATECC608 で補完することが多い | 21, 22 |
| TI | AES、SHA、PKA | PKA | 21 |
| Infineon | 品種による | AURIX HSM、OPTIGA | 21, 22 |
6. アクセラレータの落とし穴
落とし穴 1: サイドチャネル対策の有無
「AES ハードウェアがある」と「DPA に耐える AES ハードウェアがある」は別である。
| 対策 | 内容 |
|---|---|
| マスキング | 中間値をランダム値で撹乱する(09 章) |
| シャッフリング | 演算順序をランダム化する |
| ダミー演算 | 無関係な演算を混ぜる |
| 電力平坦化 | 消費電流を一定に保つ回路 |
DPA 対策の有無は、データシートに明記されているとは限らない.
セキュリティアプリケーションノートや、 PSA Certified Level 3 / SESIP 4 / CC AVA_VAN.4 以上の取得状況を見るのが確実である。 これらのレベルは物理攻撃への耐性を評価に含む(03 章)。
ST の SAES(Secure AES)のように、 「サイドチャネル対策を施した AES」を通常の AES と別に持つ SoC がある。 どちらを使うかはソフトウェアが選ぶので、 鍵を扱う処理では必ず対策版を使うこと。
落とし穴 2: DMA と共有バス
アクセラレータは DMA でデータを読むことが多い。
| 問題 | 内容 |
|---|---|
| 平文が SRAM に置かれる | 暗号化前後のデータが通常の SRAM にある |
| DMA が分離を越える | 07 章で見たとおり、DMA は TrustZone を無視しうる |
| バッファの消し忘れ | 処理後に平文が SRAM に残る |
/* 使い終わったら必ず消す */
uint8_t plaintext[64];
...
aes_encrypt(plaintext, sizeof(plaintext), ciphertext);
/* ★ コンパイラに最適化で消されないよう、専用の関数を使う */
mbedtls_platform_zeroize(plaintext, sizeof(plaintext));
/* memset() は「その後読まれない」と判断されて削除されうる */
memset()で消したつもりが消えていない、は古典的なバグである.コンパイラは「この後読まれないメモリへの書き込み」を デッドストア削除で除去してよい(規格上、正当な最適化である)。
- C11 の
memset_s()mbedtls_platform_zeroize()explicit_bzero()(BSD / glibc)volatileポインタ経由の書き込みのいずれかを使うこと。
落とし穴 3: モードの誤用
ハードウェアがあっても、使い方を間違えれば安全にならない。
| 誤用 | 何が起きるか |
|---|---|
| AES-ECB を使う | 同じ平文ブロックが同じ暗号文になる。パターンが見える |
| CTR / GCM で IV を再利用する | 鍵ストリームが再利用され、平文が復元できる(GCM では認証鍵も漏れる) |
| CBC の IV を固定値にする | 同じ平文の先頭ブロックが同じ暗号文になる |
| 認証なしの暗号(CBC 単独) | 改ざんを検出できない。パディングオラクル攻撃 |
| MAC を先に検証しない | Encrypt-then-MAC でないと危険 |
原則: AEAD(認証付き暗号)を使う.
- AES-GCM(アクセラレータ対応が多い)
- AES-CCM(BLE や Zigbee で標準)
- ChaCha20-Poly1305(ソフトウェア実装が速い)
これらは暗号化と完全性検証が一体になっているので、 「MAC を付け忘れる」「順序を間違える」という事故が起きない。
GCM の IV(ノンス)は絶対に再利用しないこと。 カウンタ方式にして、不揮発に保存するか、鍵を更新する設計にする。
7. ソフトウェア暗号ライブラリ
ハードウェアがない部分は、ソフトウェアで補う。
| ライブラリ | 特徴 |
|---|---|
| Mbed TLS | 組み込みの定番。PSA Crypto API 対応。TLS も含む |
| wolfSSL / wolfCrypt | 小さい。商用サポートあり。FIPS 140-3 認証版がある |
| tinycrypt | 極小。機能は限定的 |
| BearSSL | 定時間実装を重視 |
| libsodium | 使いやすい API。組み込みには少し大きい |
ベンダの HAL がハードウェアアクセラレータへのグルーを提供している.
Mbed TLS には ALT 実装(
MBEDTLS_AES_ALTなど)の仕組みがあり、 ベンダがハードウェアを叩く実装に差し替えられる。
- ST: STM32Cube の Mbed TLS ラッパー
- NXP: MCUXpresso SDK の els_pkc / mbedtls ポート
- Nordic: nrf_security(PSA Crypto ドライバ経由で CryptoCell / CRACEN)
- Silicon Labs: SE Manager 経由
PSA Crypto API を使っておくと、この差し替えが透過的になる。 移植性の観点でも、PSA Crypto API を第一選択にする価値がある。
8. 選定時のチェックポイント
| 項目 | 確認すること |
|---|---|
| TRNG | NIST SP 800-90B か AIS 31 準拠か。エントロピーレートは |
| 健全性テスト | オンラインテストと起動時テストがあるか |
| AES | モード(GCM / CCM / XTS)は足りるか。DPA 対策版があるか |
| ハッシュ | SHA-256 は必須。SHA-3 が要るか |
| 公開鍵 | ECC P-256 / RSA-2048 以上に対応しているか。速度は要件を満たすか |
| 鍵の扱い | 鍵スロット/ラッピングがあるか(06 章)。平文が CPU に出ないか |
| PQC | 将来必要になる。ソフトウェアで実装できる余地(Flash/RAM)はあるか |
| 認証 | PSA Certified / SESIP / CC のレベルは |
9. この章のまとめ
| ポイント | 内容 |
|---|---|
| 単一障害点 | 乱数生成器。ここが壊れると全部が壊れる |
| 組み込みの危険 | 起動直後にエントロピー源がない。ハードウェア TRNG が必須 |
| 2 段構成 | TRNG(エントロピー源)→ DRBG(高速化)。DRBG だけでは無意味 |
| 標準 | NIST SP 800-90B / AIS 31 への準拠を確認する |
| 健全性テスト | TRNG は故障し、攻撃もされる。常時テストが必要 |
| エラー処理 | 乱数取得に失敗したら止まる。0 で埋まった鍵を使わない |
| アクセラレータの効果 | 公開鍵演算で数十〜数百倍。起動時間と電池寿命に直結 |
| DPA 対策 | 「AES がある」と「DPA に耐える AES がある」は別。認証レベルで確認 |
| バッファ消去 | memset() は最適化で消える。専用の zeroize 関数を使う |
| モードの選択 | AEAD(GCM / CCM / ChaCha20-Poly1305)を使う。IV は再利用しない |
ここまでで第 II 部は終わりである。 次章から第 III 部——実際の物理攻撃がどう行われるかを見る。