Chapter 01
PSA とは何か — 仕様・実装・認証の関係をほどく
この章のゴール.
「PSA」という 3 文字が、文脈によって仕様を指したり認証を指したり 実装を指したりすることを理解し、 自分が書こうとしているコードがそのどこに乗るのかを地図の上で指せるようになること。
1. PSA は 1 つの物ではない
PSA(Platform Security Architecture、プラットフォームセキュリティアーキテクチャ)は、 Arm 社が 2017 年に提唱した、IoT 機器(Internet of Things、ネットにつながる組み込み機器)のセキュリティを「設計の型」として標準化する枠組みの総称である。 初心者が混乱する最大の理由は、この 1 つの名前の下に、性質の違う 3 種類のものが束ねられていることにある。
| 名前 | 何か | 読者にとっての意味 |
|---|---|---|
| PSA Certified(PSA 認証) | 第三者機関がデバイスやチップのセキュリティを評価する認証制度。Level 1〜3 がある | 製品を出すときに取るもの。コードには直接関係しない |
| PSA Certified APIs(PSA 機能 API) | 暗号・ストレージ・アテステーションなどの C 言語の関数仕様。仕様書は無償公開 | 本シリーズの主題。読者が呼ぶ関数はここで定義されている |
| 参照実装(TF-M、Mbed TLS) | 上の API を実際に動かすオープンソースのコード | 読者がリンクするライブラリ。関数の中身はここにある |
つまり「PSA を使う」と言ったとき、コードを書く人にとっては「PSA Certified APIs という関数群を呼ぶ」という意味である。 そして、その関数の実体は Mbed TLS や TF-M(Trusted Firmware-M)という実装が提供する。
なぜ「API を標準化する」ことに価値があるのか.
PSA 以前、マイコンで AES 暗号を使うコードは、チップベンダごとに違う関数名・違う引数・違う鍵の扱いで書かれていた。 ST のチップ用に書いたコードは NXP に持っていけば全部書き直しであり、 ハードウェア暗号エンジン(暗号計算を専用回路で行う周辺機器)を使うか ソフトウェアで計算するかによっても、呼び方が変わった。
PSA Crypto API は、「鍵を作る」「署名する」「暗号化する」という操作の呼び方を 1 つに固定した。 中身がソフトウェアでも、ハードウェア暗号エンジンでも、セキュアエレメント(鍵を外に出さずに暗号処理する専用チップ)でも、 アプリケーションのコードは同じである。 これが、本シリーズで関数の説明に力を入れる理由でもある——一度覚えれば、どのチップでも使えるからだ。
2. PSA Certified APIs の一覧
PSA 機能 API は、用途ごとに独立した仕様書として公開されている。 本シリーズで扱う範囲と、扱わない範囲を先に示す。
| API | ヘッダ | 何をするか | 本シリーズ |
|---|---|---|---|
| Crypto API | psa/crypto.h | 鍵管理、ハッシュ、MAC、暗号、AEAD、署名、鍵導出、鍵合意、乱数 | 03 章〜12 章(中心) |
| Secure Storage API | psa/internal_trusted_storage.h、psa/protected_storage.h | 小さなデータを改ざん・漏洩から守って保存する | 13 章 |
| Attestation API | psa/initial_attestation.h | 「このデバイスは何者で、どんなソフトが動いているか」の署名付き証明書を作る | 14 章 |
| Firmware Update API | psa/update.h | ファームウェア更新の受け取り・検証・切り替えを標準化 | 18 章で概要のみ |
| Secure Partition / Firmware Framework(FF-M) | psa/service.h、psa/client.h | セキュア側のサービスを部屋(パーティション)に分けて動かす仕組み | 16 章で必要な分だけ |
| Status codes | psa/error.h | 全 API 共通の戻り値 psa_status_t | 02 章 |
API の数で圧倒される必要はない。 実際のアプリケーションが日常的に呼ぶ関数は、Crypto API の中でも 20〜30 個に収まる。 本シリーズはその「よく使う 30 個」を丁寧に説明し、残りは「そういう関数もある。必要になったら仕様書のこの節を見よ」という形で逃がす。
3. コードはどこで動くのか — 2 つの配置
PSA API を呼ぶコードには、2 つのまったく違う動かし方がある。 これを最初に区別しておかないと、後の章の「鍵は外に出ない」という話が理解できない。
3.1 ライブラリとして同じ場所で動かす(Mbed TLS 単体)
Mbed TLS(Arm が主導するオープンソースの暗号・TLS ライブラリ)は、PSA Crypto API を普通の C ライブラリとして提供する。 アプリケーションと同じメモリ空間、同じ特権レベルで動く。 psa_import_key() を呼べば、鍵はライブラリ内部の配列に置かれる。
- 長所: 導入が最も簡単。PC でも動くので、まずここで API を覚えるのが正解
- 短所: アプリケーションのバグ(バッファオーバーフロー——配列の範囲外に書き込んでしまう不具合——など)で、鍵のメモリも読まれ得る。「鍵が API の外に出ない」は約束ではなく行儀にすぎない
3.2 セキュア側に置いて、壁越しに呼ぶ(TF-M)
TF-M(Trusted Firmware-M。Cortex-M(Arm のマイコン向け CPU コア)向けのセキュアファームウェアの参照実装)は、 PSA API の実体をセキュア領域(Arm TrustZone で隔離された、通常のコードから読めないメモリと CPU 状態)に置く。 アプリケーションは非セキュア領域で動き、psa_import_key() を呼ぶと、 その呼び出しは薄い橋渡しコード(ベニア、veneer)を通ってセキュア側に渡され、 セキュア側の本物の関数が実行されて、結果だけが返ってくる。
- 長所: 鍵は物理的に非セキュア側から読めない。アプリケーションが乗っ取られても鍵は守られる
- 短所: 構築が難しい。呼び出しごとに切り替えのコスト(数 µs)がかかる
重要なのは、どちらの配置でもアプリケーションのソースコードが同じだということである。 PSA API は「関数の呼び方」だけを決め、「どこで実行されるか」は決めない。 だから、まず Mbed TLS 単体で API を覚え、製品では TF-M に載せ替える、という進め方ができる。 本シリーズの 03 章〜14 章は配置に依存しない書き方をし、15 章と 16 章で 2 つの配置それぞれの具体的な作り方を扱う。
4. 「鍵が外に出ない」という設計思想
PSA Crypto API のすべての設計は、1 つの思想から派生している。
鍵の値をアプリケーションに渡さない。アプリケーションは鍵の「番号」だけを持つ。
従来のライブラリでは、AES で暗号化するには 16 バイトの鍵をバイト配列としてアプリケーションが持ち、それを関数に渡した。 PSA では、鍵をライブラリに預ける(psa_import_key())と、 引き換えに 鍵 ID(psa_key_id_t、32 ビットの整数)が返ってくる。 以後、暗号化も署名も、アプリケーションは鍵 ID を渡すだけであり、鍵の値には二度と触らない。
psa_key_id_t key; /* 鍵の「番号」。値ではない */
psa_import_key(&attributes, key_bytes, 16, &key);
memset(key_bytes, 0, 16); /* 預けたので、手元の値はもう要らない */
/* 以後は番号だけで使う */
psa_cipher_encrypt(key, PSA_ALG_CTR, plain, plain_len, out, sizeof out, &out_len);この設計が、03 章で扱う「属性」という概念につながる。 鍵を預けるときに「この鍵は AES-CTR の暗号化にしか使えない」「エクスポート(値の取り出し)は禁止」と用途を宣言し、 以後ライブラリがそれを強制する。 用途を宣言し忘れると、後で PSA_ERROR_NOT_PERMITTED というエラーで止まる——初心者が最初に踏む地雷である。
5. 本シリーズの読み方
各章は次の構成で書かれている。
- その章の操作が「何をするものか」を、暗号の予備知識なしで説明する
- 一発関数(single-part)——1 回の呼び出しで完結する関数を先に覚える
- 分割関数(multi-part)——大きなデータを少しずつ処理する関数群を、状態遷移として理解する
- サイズを決めるマクロ——バッファをいくつ確保すべきかを計算するマクロ
- 落とし穴——実際に踏む順に並べたエラーの原因
- 仕様書に逃がす——めったに使わない関数の名前と、仕様書のどこを見るか
暗号そのものの理論(AES の内部構造、楕円曲線の数学など)は扱わない。 それは 暗号編 にある。 本シリーズは「その暗号を PSA の関数でどう呼ぶか」に集中する。
仕様書の読み方.
PSA Certified Crypto API の仕様書(バージョン 1.3 が 2025 年時点の最新)は、 arm-software.github.io/psa-api で HTML として公開されている。 各関数のページは「Parameters / Returns / Description」の形式で、関数を知っている人が引数を確認するための辞書である。 本シリーズは、その辞書を引けるようになるまでの「読み物」だと思ってほしい。
6. 開発環境を用意する
API を覚えるだけなら、PC 上の Mbed TLS で十分である。 PSA Crypto API は Mbed TLS 2.x 系の後半から入り、3.x 系で成熟し、Mbed TLS 4.0(2025 年末)からは PSA が唯一の暗号 APIになった (暗号部分は TF-PSA-Crypto という別リポジトリに切り出された。15 章)。
git clone https://github.com/Mbed-TLS/mbedtls.git
cd mbedtls
git submodule update --init # 4.x では tf-psa-crypto を取り込む
cmake -B build
cmake --build build最初のプログラムは、初期化してハッシュを 1 つ計算するだけでよい。
#include "psa/crypto.h"
#include <stdio.h>
int main(void)
{
psa_status_t st = psa_crypto_init(); /* 全 API の前に必ず 1 回 */
if (st != PSA_SUCCESS) { printf("init failed: %d\n", (int)st); return 1; }
const char *msg = "hello";
uint8_t hash[PSA_HASH_LENGTH(PSA_ALG_SHA_256)]; /* 32 バイト */
size_t hash_len;
st = psa_hash_compute(PSA_ALG_SHA_256, (const uint8_t *)msg, 5,
hash, sizeof hash, &hash_len);
printf("status=%d len=%u first=%02x\n", (int)st, (unsigned)hash_len, hash[0]);
return 0;
}この 10 行に、PSA API の作法がほぼ全部入っている—— 初期化、戻り値 psa_status_t、アルゴリズムを表す定数、サイズを計算するマクロ、出力バッファと実際の長さのペア。 次章で、この作法を 1 つずつ確かめる。
7. 実装と仕様の対応を確かめる
仕様と実装の地図を歩く
この章のポイント
- PSA は認証制度・API 仕様・参照実装の 3 つの総称であり、コードを書く人にとっては「PSA Certified APIs という関数群」を指す
- 中心は Crypto API。日常的に使う関数は 20〜30 個
- 同じソースコードが、Mbed TLS 単体(同じ場所で動く)でも TF-M(壁越しに呼ぶ)でも動く
- 設計思想は「鍵の値をアプリケーションに渡さない」。アプリケーションは鍵 ID だけを持つ