ハードウェア:
ソフトウェア:
[入門] Yocto Linux BSPのビルド方法 - i.MX FRDMボード編 (日本語ブログ)
repo init -u https://github.com/nxp-imx/imx-manifest -b imx-linux-whinlatter -m imx-6.18.2-1.0.0.xml
DISTRO=fsl-imx-wayland MACHINE=imx93-11x11-lpddr4x-frdm source imx-setup-release.sh -b ./buildPKCS#11(Public-Key Cryptography Standards #11)は、暗号処理を行うハードウェアやソフトウェア(例:HSM、スマートカード、USBトークンなど)をアプリケーションから統一的に利用するためのAPI仕様です。別名「Cryptoki(クリプトキー)」とも呼ばれます。
PKCS#11を使用するアプリケーションとして、今回はpkcs11-toolを使用します。
imx-smwを含めた関係を図示すると以下のようになります。
PKCS#11を使用するアプリケーション(pkcs11-tool etc.)
↓ (PKCS#11 API経由での使用)
imx-smw
↓
imx-secure-enclave
↓
EdgeLock Secure Enclave Hardwareまた、以前のOpenSSL経由でのSE050の使用方法の記事では、Plug and Trust Middlewareに含まれるopenssl providerを使用してopenssl経由での使用方法を解説しました。
SMWはopenssl providerを提供しませんが、pkcs11-providerを使用することでopensslからPKCS#11のインターフェースを使用可能なため、openssl経由でのELEの使用も可能です。
GitHub - openssl-projects/pkcs11-provider: A pkcs#11 provider for OpenSSL 3.0+ · GitHub
OpenSSL provider非使用時と、imx-smw + PKCSを使用する場合の関係を図示すると以下のようになります。
Provider非使用時はkeyがファイルとしてファイルシステム上に存在し、暗号処理もソフトウェアにより行われます。
imx-smwおよびpkcs11-provider使用時はkeyおよび暗号処理はELEハードウェアにより保護されます。使用するkeyはコード上またはファイルシステム上にあるPKCS#11 URIにより指定します。
note : Plug and Trust MiddlewareもPKCS#11のAPIを提供しています。
systemctl start nvm_daemon
systemctl status nvm_daemonsystemctl enable nvm_daemonexport MODULE_PKCS11=/usr/lib/libsmw_pkcs11.so.5pkcs11-tool --module $MODULE_PKCS11 -LAvailable slots:
Slot 0 (0x0): Security Middleware Abstraction
token label : smw
token manufacturer : NXP Semiconductor
token model :
token flags : login required, PIN pad present, token initialized
hardware version : 0.0
firmware version : 0.0
serial num :
pin min/max : 0/0
uri : pkcs11:model=;manufacturer=NXP%20Semiconductor;serial=;token=smwpkcs11-tool --module $MODULE_PKCS11 --login -Opkcs11-tool --module $MODULE_PKCS11 \
--login \
--keypairgen \
--key-type EC:prime256v1 \
--id 02 \
--label "MyECCKey" \
--usage-sign \
--allowed-mechanisms "ECDSA-SHA256"Using slot 0 with a present token (0x0)
Profile object 250360144
profile_id: CKP_BASELINE_PROVIDER (1)
Public Key Object; EC EC_POINT 256 bits
EC_POINT: 044104fe4c97a7a4f54702f9fc5740f62c0864e851098dc43cb4c9ba8633421e5bc362cdc559523118bb4fe4281851c051e24a88846a2d774eb3f928595761cf719e90
EC_PARAMS: 06082a8648ce3d030107 (OID 1.2.840.10045.3.1.7)
label: MyECCKey
ID: 02
Usage: verify
Access: none
Unique ID:
uri: pkcs11:model=;manufacturer=NXP%20Semiconductor;serial=;token=smw;id=%02;object=MyECCKey;type=public
Private Key Object; EC
label: MyECCKey
ID: 02
Usage: sign
Access: sensitive, always sensitive
Unique ID:
uri: pkcs11:model=;manufacturer=NXP%20Semiconductor;serial=;token=smw;id=%02;object=MyECCKey;type=privateecho hello > message.txt
pkcs11-tool --module $MODULE_PKCS11 \
--login \
--sign \
--id 02 \
--mechanism ECDSA-SHA256 \
--input-file message.txt \
--output-file signature.bin
pkcs11-tool --module $MODULE_PKCS11 \
--login \
--verify \
--id 02 \
--mechanism ECDSA-SHA256 \
--input-file message.txt \
--signature-file signature.binopenssl_conf = openssl_init
[openssl_init]
providers = provider_sect
[provider_sect]
default = default_sect
pkcs11 = pkcs11_sect
[default_sect]
activate = 1
[pkcs11_sect]
module = /usr/lib/ossl-modules/pkcs11.so
pkcs11-module-path = /usr/lib/libsmw_pkcs11.so.5
activate = 1export OPENSSL_CONF=<作成したopenssl.cnfの絶対path>openssl pkeyutl -sign -inkey "pkcs11:object=MyECCKey;type=private" -in message.txt -out sig.bin -digest sha256
openssl pkeyutl -verify -pubin -inkey "pkcs11:object=MyECCKey;type=public" -in message.txt -sigfile sig.bin -digest sha256python3 uri2pem.py --out MyECCKey.pem "pkcs11:object=MyECCKey;type=private"
詳細は確認できておりませんが、uri2pem.pyの内容を確認する限りprivate key以外のURIのpemファイルは作成できないようです。
生成された「MyECCKey.pem」を署名時のkeyとして指定することで先ほどと同様の動作が可能です。
openssl pkeyutl -sign -inkey MyECCKey.pem -in message.txt -out sig.bin -digest sha256
openssl pkeyutl -verify -pubin -inkey "pkcs11:object=MyECCKey;type=public" -in message.txt -sigfile sig.bin -digest sha256openssl req -new -key "pkcs11:object=MyECCKey" -outform PEM -subj /CN=frdmimx93_test -out frdmimx93_test.csr -sha256
openssl req -text -noout -in frdmimx93_test.csrその後ホストPC側に「frdmimx93_test.csr」を移動し、以下を実行します。
openssl ecparam -genkey -name prime256v1 -out rootCA_key_pair.pem
openssl req -new -x509 -subj /CN=rootCA -key rootCA_key_pair.pem > rootCA_cert.cer
openssl x509 -req -in frdmimx93_test.csr -days 365 -CA rootCA_cert.cer -CAkey rootCA_key_pair.pem -out frdmimx93_test_cert.cer
作成した「frdmimx93_test_cert.cer」をFRDM-IMX93に戻します。後ほど「MyECCKey.pem」とセットで使用するため、そちらを作成したディレクトリに置きます。
また、Azure IoT Hubにて、作成した「rootCA_cert.cer」の登録、「frdmimx93_test」という名前のデバイスの作成を行います。
手順は以下記事の「Azure IoT Hubへの中間CA証明書の追加」の章を参照ください。
注 : 前述のとおりここで登録した証明書はテスト用のため、動作確認後は削除を推奨します。
export IOT_HUB_NAME=ShinjiIotHubTest
export DEVICE_NAME=frdmimx93_test
mosquitto_pub -h "${IOT_HUB_NAME}.azure-devices.net" -p 8883 -u "${IOT_HUB_NAME}.azure-devices.net/${DEVICE_NAME}/api-version=2016-11-14" -t "devices/${DEVICE_NAME}/messages/events/" -m '{"mes":"Hello Azure with i.MX93!"}' --capath /etc/ssl/certs/ --cert frdmimx93_test_cert.cer --key MyECCKey.pem -i ${DEVICE_NAME} -d -q 1以下のような出力が出れば成功です。
Client frdmimx93_test sending CONNECT
Client frdmimx93_test received CONNACK (0)
Client frdmimx93_test sending PUBLISH (d0, q1, r0, m1, 'devices/frdmimx93_test/messages/events/', ... (34 bytes))
Client frdmimx93_test received PUBACK (Mid: 1, RC:0)
Client frdmimx93_test sending DISCONNECT
以下記事の「IoT Hubへ送信されたメッセージの確認とデバイスへのメッセージ送信」の手順を使用するとAzure IoT Hub側のCloud Shellでも受信メッセージを確認できます。
=========================
本投稿の「Comment」欄にコメントをいただいても、現在返信に対応しておりません。
お手数をおかけしますが、お問い合わせの際には「NXPへの技術質問 - 問い合わせ方法 (日本語ブログ)」をご参照ください。
(既に弊社NXP代理店、もしくはNXPとお付き合いのある方は、直接担当者へご質問いただいてもかまいません。)