概要
今回は、dsPIC33AKシリーズの第2世代(2nd Generation)に搭載されている暗号化アクセラレータの使い方についてご紹介します。
dsPIC33AKxxxMPS シリーズはセキュア機能も強化されております。今回は暗号化アクセラレータについてご紹介いたします。暗号処理は計算負荷が高いことが多く、専用のハードウェア(暗号化アクセラレータ)で高速化します。これによりCPU負荷を軽減し、セキュアな通信やデータ保護をリアルタイムに実現可能です。
記事変更履歴
| 公開/ 変更日 | 特記 |
| 25/5/25 | 初版公開。 |
| 25/5/26 | 対応型式の追加 |
| 25/7/6 | ・ECDHライブラリに関する項目を追加 ・ECDSAライブラリに関する項目を追加 ・HASHライブラリに関する項目を追加 ・PKEライブラリに関する項目を追加 ・TRNGライブラリに関する項目と実行例を追加 |
関連リンク
内部リンク
外部リンク
暗号化について

暗号化の必要性
暗号化の必要性は、主に以下のような点が挙げられます。
情報の秘密保持
ネット通信やデータ保存時に、第三者に内容を見られないようにするため。
改ざん防止
データが途中で勝手に変更されていないか確認するため。
認証とアクセス制御
正当なユーザーだけがデータにアクセスできるようにするため。
暗号化の種類について
ここでは、dsPIC33AKシリーズ 第2世代で新たに対応した暗号化技術(Cryptographic Features)について解説します。
AES(Advanced Encryption Standard)

■AESとは
アメリカのNIST(米国標準技術研究所)が定めた対称鍵暗号の標準規格(FIPS 197準拠)。同じ鍵で暗号化と復号を行う。
■鍵長
AES-128(128ビット鍵)、AES-192、AES-256(256ビット鍵)の3種類。
■モード
データをどのように分割・連結して暗号化するかの方式。代表的なモードは以下。
| 対応 | Github demo v1.00 | モード | 特徴 |
| 〇 | 〇 | ECB (Electronic Codebook) | 各ブロックを独立して暗号化。単純だが、同じ平文は同じ暗号文になるため安全性は低い。 |
| 〇 | CBC (Cipher Block Chaining) | 各ブロックの暗号文が次のブロックの暗号化に影響。初期化ベクトル(IV)必須。 | |
| 〇 | CFB (Cipher Feedback) / OFB (Output Feedback) | ストリーム暗号のように連続的に暗号化。同期型の暗号モード。 | |
| 〇 | OFB (Output Feedback Mode) | OFBモードは、ブロック暗号をストリーム暗号のように利用する動作モードの一つです。このモードでは、まず初期化ベクトル(IV)を暗号化し、その出力を次の暗号化の入力として繰り返し使用します。生成された暗号出力は、平文とXOR演算を行うことで暗号文を生成します。 このようにして得られる暗号文は、同じ鍵とIVが使用されれば、常に同じ暗号化出力系列を得ることができるため、エラー伝播を抑制しつつ、同期がとれていれば部分的な復号も可能です。 | |
| 〇 | 〇 | CTR (Counter) | カウンター値を暗号化し、その結果と平文をXORする。並列処理が可能。 |
| 〇 | 〇 | GCM (Galois/Counter Mode) | CTRモードに認証タグを加えた認証付き暗号(AEAD)で高速かつ安全。 |
| 〇 | CCM (Counter with CBC-MAC) | 認証付き暗号。GCMとは別のAEAD方式。 | |
| 〇 | XTS | ストレージ暗号向けのモード。セクターごとに異なる鍵とカウンターで暗号化。 | |
| 〇 | 〇 | CMAC (Cipher-based Message Authentication Code) | メッセージ認証コード生成に用い、データの完全性と認証を確保。 |
■信頼性について
AESは現時点で幅広い分野で応用され、暗号アルゴリズムの中でも高い信頼性を持っています。しかしながら将来的に量子コンピュータの発展により、セキュリティが突破されてしまう可能性もあると言われています、
ハッシュ関数とHMAC

■ハッシュ関数とは
ハッシュ関数は、任意の固定長のデータから固定長のデータ(ハッシュ値)に変換する関数です。
ハッシュ値はデータの「指紋」のようなもので、データが少しでも変わると大きく変わります。
これにより、データが改ざんされていないかを簡単にチェックできます。
■特徴
・固定長出力
入力がどれだけ長くても常に一定の長さの出力を返します。
・アバランシェ効果
もともと「ハッシュ関数」の性質は、半導体における“ある閾値を超えると急激に状態が変化する”という現象になぞらえて表現されることがあります。
ハッシュ関数においては、「入力がほんの少し違うだけでも、出力(ハッシュ値)が大きく変化する」という性質を指します。
この性質によって、ハッシュ値から元のデータを逆算することは非常に困難となっており、セキュリティ用途に適しています。
・決定性
同じ入力をハッシュ関数にかけると、必ず同じ出力を返します。
・一方向性
ハッシュ値から元の入力データを復元する事は現時点で基本的に不可能とされています。
■モード
以下の種類に対応しています。
| 対応 | Github demo v1.00 | モード | 特徴 |
| 〇 | 〇 | SHA-1 | 160ビット出力。安全性は弱く推奨されない |
| 〇 | 〇 | SHA-224, SHA-256 | 256ビット出力で広く使われる |
| 〇 | 〇 | SHA-384, SHA-512 | より長い出力で強力 |
■利用シーン
・パスワード保護
パスワードをそのまま保存せず、ハッシュ化して保存。万が一漏れても、元のパスワードがわかりにくい。これらによりWiFiのパスワードやファイルとデータベースの暗号化などに使用されています。
・デジタル署名の基礎
デジタル署名ではまずデータのハッシュをとり、そのハッシュを暗号化して署名とする。
■HMAC(Hash-based Message Authentication Code)
秘密鍵とハッシュ関数を組み合わせ、メッセージの認証と完全性を検証。
公開鍵暗号(Public Key Cryptography)

■公開鍵暗号とは
公開鍵暗号は、2つの鍵(ペア)を使う暗号方式です。
- 公開鍵(Public Key)
みんなに公開していい鍵。これで暗号化すると、対応する秘密鍵でしか復号できない。 - 秘密鍵(Private Key)
絶対に他人に知られてはいけない鍵。公開鍵で暗号化されたデータは、この秘密鍵でのみ復号可能。
■特徴
・秘密鍵を相手に渡さずに安全に通信できる
例:あなたの公開鍵をみんなに渡し、誰でもそれでメッセージを暗号化できるが、復号できるのはあなたの秘密鍵だけ。
・デジタル署名
秘密鍵で署名し、公開鍵で検証することで、「確かにあなたが作成した」ことを証明できる。
・なぜ公開鍵が重要?
対称鍵暗号(AESなど)は、同じ鍵で暗号化・復号するので、その鍵のやりとりが問題になる。
公開鍵暗号は鍵の交換問題を解決し、安全な鍵交換や認証に使える。
■モード
| 対応 | Github demo v1.00 | モード | 特徴 |
| 〇 | RSA (Rivest-Shamir-Adleman) | 最も古典的な公開鍵暗号。大きな素数の積を使う。鍵長最大4096ビットまで対応。 中国剰余定理(CRT)を使うことで復号処理の高速化が可能。 | |
| 〇 | DSA (Digital Signature Algorithm) | デジタル署名用アルゴリズム。鍵長最大2048ビット対応。 | |
| 〇 | 〇 P-192 P-256 P-384 P-521 | ECC(Elliptic Curve Cryptography) | 楕円曲線を使った公開鍵暗号で、RSAより短い鍵長で同等の安全性を提供。 ECDSA:楕円曲線署名/検証アルゴリズム。 曲線の種類: 素数体 (Prime field): P-192, P-224, P-256, P-384, P-521 二進体 (Binary field): K-163, K-233, K-283, K-409, K-571 二進体別種: B-163, B-233, B-283, B-409, B-571 |
| 〇 | EdDSA (Edwards-curve Digital Signature Algorithm) | エドワーズ曲線を使った高速かつ安全な署名アルゴリズム。 | |
| 〇 | JPAKE / SRP | パスワード認証付きの鍵共有プロトコル。パスワードを用いて安全に共通鍵を生成する。 | |
| 〇 | Rabin Miller primality test | 素数判定の確率的アルゴリズム。公開鍵生成時に素数判定に使用。 | |
| 〇 | ECDH / ECDHE (Elliptic Curve Diffie Hellman) | 楕円曲線版のDiffie-Hellman鍵交換。鍵の共有に用いる。ECDHEはエフェメラル(短命)鍵を使うことで前方秘匿性を強化。 |
真の乱数生成器(True Random Number Generator: TRNG)

■真の乱数発生器とは
コンピュータでよく使用される疑似乱数発生器は数学的なアルゴリズムをもちいて、乱数を生成します。シード(初期値)が分かれば予測可能で再現性も有ります。
真の乱数発生器はハードウェアからのノイズなど予測不能な情報を元に真の乱数を生成し、予測性や再現性が無いことからキュリティや暗号において極めて重要な役割を果たします。
■特徴
dsPIC33AK 2世代目に搭載されているTRNGはNIST-800-22とNIST-800-90Bの基準に準拠しており、
暗号鍵生成や初期化ベクトル生成に不可欠です。
■モード
| 対応 | Github demo v1.00 | モード | 特徴 |
| 〇 | 〇 | – |
鍵生成機能
NIST-800-133(鍵生成ガイドライン)やNIST-186-4(デジタル署名規格)に準拠した鍵生成機能。
CAVP認証対応
Cryptographic Algorithm Validation Program (CAVP) はNISTの暗号アルゴリズム検証プログラム。
本暗号化アクセラレータはCAVP認証に対応可能で、政府・企業の高セキュリティ要求に応える。
開発環境
開発環境を以下に示します。
今回はCPUボード(EV80L65A)で動作確認を行います。
| 項目 | 値 | リンク |
| ベースボード | dsPIC33A CURIOSITY PLATFORM DEVELOPMENT BOARD | dsPIC33A Curiosity Platform Development Board User’s Guide (microchip.com) |
| CPUボード(EV80L65A) | dsPIC33AK512MPS512 General Purpose Dual In-Line Module (DIM) | dsPIC33AK512MPS512 General Purpose Dual In-Line Module (DIM) | Microchip Technology |
| 統合開発環境 | MPLAB X IDE v6.25 | MPLAB® X IDE | Microchip Technology |
| コンパイラ | MPLAB XC DSC v3.21 | MPLAB® XC DSC Compiler | Microchip Technology |

暗号化アクセラレータライブラリについて
1.概要
暗号化アクセラレータは、レジスタを直接操作するのではなく、提供されているアセンブラライブラリを利用して制御します。また、基本的な処理を簡単に呼び出せるラッパー関数も用意されているため、使い方の基本を押さえれば、自分のプロジェクトにもスムーズに組み込めるはずです。
2.GitHubデモサンプル
以下のページに暗号化アクセラレータを利用したデモコードが公開されています。執筆時点(25/5/25)ではバージョンが1.0.0が上がっていましたのでダウンロードします。
3.APIドキュメント
以下のページに、関連するAPIドキュメントが公開されています。
なお、執筆時点(2025年5月25日)では未掲載の情報も一部含まれているため、今後の更新により内容が追加・変更される可能性があります。
CAM Hardware Driver API Documentation
AESライブラリ(cam_aes.h)
概要
Ver.1.0.0のAPIライブラリでは、以下のモードに対応しています。
対応モードは限定的ではありますが、今後のバージョンアップにより、さらなるモードの追加対応が期待されます。将来的な拡張予定についての詳細は、公式のリリースノートや更新履歴をご確認ください。
・ECB (Electronic Codebook)
・CTR (Counter)
・GCM (Galois/Counter Mode)
・CMAC (Cipher-based Message Authentication Code)
関連リンク
関数一覧
AESのドライバAPIは以下の関数が用意されています。
| 関数名 | 機能概要 | 主な引数 | 戻り値(成功/失敗) |
|---|---|---|---|
DRV_CRYPTO_AES_IsrHelper() | AES割り込み処理のヘルパー関数(内部処理用) | なし | なし |
DRV_CRYPTO_AES_Initialize() | AES演算の初期化 | contextData, mode, operation, key, keyLength, initVector, initVectorLength | AES_NO_ERROR / AES_STATE_ERROR, AES_INITIALIZE_ERROR |
DRV_CRYPTO_AES_AddHeader() | ヘッダデータ(AADなど)の追加 | contextData, headerData, headerLength | AES_NO_ERROR / AES_STATE_ERROR, AES_WRITE_ERROR |
DRV_CRYPTO_AES_AddInputData() | 入力データの追加 | contextData, data, dataLength | AES_NO_ERROR / AES_STATE_ERROR, AES_WRITE_ERROR |
DRV_CRYPTO_AES_AddOutputData() | 出力データ用バッファの登録 | contextData, data, dataLength | AES_NO_ERROR / AES_STATE_ERROR, AES_WRITE_ERROR |
DRV_CRYPTO_AES_DiscardData() | 出力データから指定バイト数を破棄 | contextData, discardLength | AES_NO_ERROR / AES_STATE_ERROR, AES_WRITE_ERROR |
DRV_CRYPTO_AES_AddLenALenC() | AES-GCM用のLenA/LenC情報の追加 | contextData | AES_NO_ERROR / AES_STATE_ERROR, AES_WRITE_ERROR |
DRV_CRYPTO_AES_Execute() | AES演算の実行(CMAC計算や暗号処理) | contextData | AES_NO_ERROR / AES_STATE_ERROR, AES_EXECUTE_ERROR |
DRV_CRYPTO_AES_IsActive() | AES演算の進行中かどうかを取得 | contextData, active(ポインタ) | AES_NO_ERROR / AES_CONTEXT_ERROR, AES_STATE_ERROR |
DRV_CRYPTO_AES_GetContextSize() | AES用のコンテキストサイズを取得 | contextData | コンテキストサイズ(バイト単位) |
3.サンプルプロジェクトのコール図例
以下に、サンプルプロジェクトにおけるAPIライブラリコールの構成例(コール図)を示します。
このコール図は、各関数間の呼び出し関係を視覚的に把握できるようにしたものです。
本サンプルプロジェクトは、単一のモードだけでなく、複数のモードをテスト可能な構成となっているため、関数の階層構造が非常に深く、全体の関係性を把握するのがやや難解です。
そのため、処理の流れや依存関係を正確に理解するには、個々の関数を段階的に追いながら読み解いていくことが重要です。特に主要な初期化処理や、各モードに固有の関数の役割を整理しながら見ることで、全体像が掴みやすくなります。








ECDHライブラリ(cam_ecdh.h)
概要
ECDH(Elliptic Curve Diffie–Hellman)は、楕円曲線暗号(ECC: Elliptic Curve Cryptography)を利用した鍵共有プロトコルです。ECDHを使うことで、通信する両者が事前に共有秘密を持たずに、安全に共通の「共通鍵(セッション鍵)」を生成できます。この鍵は以後の通信の暗号化(例えばAESなど)に使われます。
特徴と利点
| 項目 | 内容 |
|---|---|
| 🔒 安全性 | 楕円曲線上の離散対数問題は計算困難で、RSAと同等の安全性をより短い鍵長で実現(例:256bit ECC ≒ 3072bit RSA) |
| 📏 鍵のサイズ | 小さくて済むため、省メモリ・低帯域・高速 |
| 📡 応用 | TLS、SSH、Signalなど多数のプロトコルで利用されている |
関連リンク
関数一覧
ECDHのドライバAPIは以下の関数が用意されています。
| 関数名 | 機能概要 | 主な引数 | 戻り値(成功/失敗) |
|---|---|---|---|
| DRV_CRYPTO_ECDH_GetSharedSecret() | 共有シークレットを生成します | * eccData,* secret,secretLength | CRYPTO_PKE_RESULT_SUCCESS/CRYPTO_PKE_RESULT_ERROR_FAIL |
DRV_CRYPTO_ECDH_InitEccParams() | 共有シークレットの生成に使用する ECDH パラメータを初期化します。 | *eccData,privateKey,privateKeyLength,* publicKey,publicKeyLength,hwEccCurve | CRYPTO_PKE_RESULT_SUCCESS/CRYPTO_PKE_RESULT_ERROR_FAIL |
ECDSAライブラリ(cam_ecdsa.h)
概要
ECDSA(Elliptic Curve Digital Signature Algorithm)は、楕円曲線暗号(ECC)に基づくデジタル署名アルゴリズムです。ECDHが「鍵交換」なら、ECDSAは「署名と検証」に使います。
関連リンク
関数一覧
ECDSAのドライバAPIは以下の関数が用意されています。
| 関数名 | 機能概要 | 主な引数 | 戻り値(成功/失敗) |
|---|---|---|---|
| DRV_CRYPTO_ECDSA_InitEccParamsSign() | 署名の生成に使用する ECDSA パラメータを初期化します。 | * eccData, * inputHash, hashLength, * privateKey, privateKeyLength, eccCurve | CRYPTO_PKE_RESULT_SUCCESS/CRYPTO_PKE_RESULT_ERROR_FAIL |
| DRV_CRYPTO_ECDSA_Sign() | 署名を生成し、出力を入力署名バッファに設定します。 | * eccData, * outputSignature, signatureLength | CRYPTO_PKE_RESULT_SUCCESS/CRYPTO_PKE_RESULT_ERROR_FAIL |
| DRV_CRYPTO_ECDSA_InitEccParamsVerify() | 署名検証のために ECDSA パラメータを初期化します。 | * eccData, * inputHash, *inputSignature signatureLength, *publicKey, publicKeyLength, eccCurve | CRYPTO_PKE_RESULT_SUCCESS/CRYPTO_PKE_RESULT_ERROR_FAIL |
DRV_CRYPTO_ECDSA_Verify() | 署名検証を実行し、結果を返します。 | * eccData | CRYPTO_PKE_RESULT_SUCCESS/CRYPTO_PKE_RESULT_ERROR_FAIL |
HASHライブラリ(cam_hash.h)
概要
ハッシュ関数は、任意の固定長のデータから固定長のデータ(ハッシュ値)に変換する関数です。
関連リンク
関数一覧
| 関数名 | 機能概要 | 主な引数 | 戻り値(成功/失敗) |
|---|---|---|---|
| DRV_CRYPTO_HASH_Digest() | 1 つのハッシュ操作を実行してダイジェストを生成します。 | * contextData, mode, * data, dataLength, * digest, digestLength | HASH_NO_ERROR(正常), HASH_CONTEXT_ERROR , HASH_INITIALIZE_ERROR , HASH_STATE_ERROR , HASH_EXECUTE_ERROR |
| DRV_CRYPTO_HASH_Final() | ハッシュ操作を実行して、最終的なダイジェストを生成します。 | * contextData | HASH_NO_ERROR(正常), HASH_CONTEXT_ERROR , HASH_INITIALIZE_ERROR , HASH_STATE_ERROR , HASH_EXECUTE_ERROR |
| DRV_CRYPTO_HASH_GetContextSize() | ハッシュコンテキストブロックのサイズを取得します。 | * contextData | ハッシュ コンテキスト ブロックのサイズ |
DRV_CRYPTO_HASH_Initialize() | 新しいハッシュ操作を初期化します。 | * contextData, mode | CRYPTO_PKE_RESULT_SUCCESS/CRYPTO_PKE_RESULT_ERROR_FAIL |
| DRV_CRYPTO_HASH_IsActive() | ハッシュ操作がアクティブかどうかを返します。 | * contextData, * active | CRYPTO_PKE_RESULT_SUCCESS/CRYPTO_PKE_RESULT_ERROR_FAIL |
| DRV_CRYPTO_HASH_IsrHelper() | HASH 操作用の ISRヘルパー | 無し | 無し |
| DRV_CRYPTO_HASH_Update() | ハッシュ操作にデータを追加します | * contextData, * data, dataLength, | CRYPTO_PKE_RESULT_SUCCESS/CRYPTO_PKE_RESULT_ERROR_FAIL |
PKEライブラリ(cam_pke.h)
概要
関連リンク
関数一覧
| 関数名 | 機能概要 | 主な引数 | 戻り値(成功/失敗) |
|---|---|---|---|
| DRV_CRYPTO_PKE_IsrHelper | HASH 操作用の ISRヘルパー | 無し | 無し |
TRANGライブラリ(cam_trng.h)
概要
真の乱数を発生させるために使用します
関連リンク
関数一覧
| 関数名 | 機能概要 | 主な引数 | 戻り値(成功/失敗) |
|---|---|---|---|
| DRV_CRYPTO_TRNG_IsrHelper() | 乱数発生用 ISRヘルパー | 無し | 無し |
| DRV_CRYPTO_TRNG_ReadData | 乱数データ取得 | * data, size | TRNG_ERROR |
| DRV_CRYPTO_TRNG_Setup() | 乱数初期化 | 無し | 無し |
実行例
①GitHubからダウンロードしたlibraryフォルダ以下のファイルを、自身のプロジェクトフォルダにコピーします。

②プロジェクトにライブラリ「libcam05346-dspic33.a」を追加します。

③下記のソースファイルをビルド・実行して動作を確認します。
#include <stdio.h>
#include <stdlib.h>
#include <xc.h>
#include <dsp.h>
#include "cam_trng.h"
uint8_t trng[10];
int main(void)
{
vdg_Clock_Set_Register(); /* クロック初期化 */
DRV_CRYPTO_TRNG_Setup();
DRV_CRYPTO_TRNG_ReadData(trng,10);
while (1)
{
Nop();
}
}
結果
tragを確認すると、10バイト分のランダムなデータが生成されていることがわかります。

対応型式
対応型式は以下の通りです。
・dsPIC33AK256MC205・dsPIC33AK256MC206・dsPIC33AK256MC208・dsPIC33AK256MC210・dsPIC33AK256MC505
・dsPIC33AK256MC506・dsPIC33AK256MC508・dsPIC33AK256MC510・dsPIC33AK512MC205・dsPIC33AK512MC206
・dsPIC33AK512MC208・dsPIC33AK512MC210・dsPIC33AK512MC505・dsPIC33AK512MC506・dsPIC33AK512MC508
・dsPIC33AK512MC510
・dsPIC33AK256MPS205・dsPIC33AK256MPS206・dsPIC33AK256MPS208・dsPIC33AK256MPS210・dsPIC33AK256MPS212
・dsPIC33AK256MPS505・dsPIC33AK256MPS506・dsPIC33AK256MPS508・dsPIC33AK256MPS510・dsPIC33AK256MPS512
・dsPIC33AK512MPS205・dsPIC33AK512MPS206・dsPIC33AK512MPS208・dsPIC33AK512MPS210・dsPIC33AK512MPS212
・dsPIC33AK512MPS505・dsPIC33AK512MPS506・dsPIC33AK512MPS508・dsPIC33AK512MPS510・dsPIC33AK512MPS512
記事についての注意点
本記事は慎重に内容を検討し正確さに努めておりますが、内容に誤りがあったとしても、この記事を参考にして生じた損害等については一切の責任を負いません。


コメント