はじめに
Security Key Management Toolは、KUKによりユーザ鍵を暗号化し、ユーザ鍵のEncrypted Keyを得ることができます。
Security Key Management Tool
「鍵のラッピング」タブの「鍵の種類」タブで以下の設定をします。
鍵の種類:ユーザ鍵の種類に応じてAES/RSA/ECC/HMACを選択します。
ラッピング鍵:KUKを選択し、UFPKファイルとしてKUKの平文鍵を指定します。
出力:バイナリを選択し、出力ファイル名(.bin)を指定します。
「鍵データ」タブに移動し、以下の設定をします。
ファイル:ユーザ鍵の平文鍵を指定します。バイナリ(.key)に加えPEM形式(.pem)のファイルを選択できます。
上記設定後、「ファイルを生成する」をクリックすると「出力」に指定したファイルにバイナリ形式で出力が生成されます。
バイナリファイルのフォーマットはドキュメントまたはCソースでの出力に記載があります。
出力形式をCソースにすると以下のようになるはずです(具体的な値は異なる)。
const encrypted_user_key_data_t g_encrypted_user_key_data =
{
/* uint32_t keytype; */
0x00000000,
/* uint32_t shared_key_number; */
0x00000000,
/* uint8_t initial_vector[16]; */
{
0x06, 0x29, 0xDA, 0x17, 0x11, 0xD5, 0xC3, 0x9B, 0x5F, 0x3B, 0x51, 0x9A, 0xC6, 0xD2, 0x2E, 0x99
},
/* uint8_t encrypted_user_key[ENCRYPTED_KEY_BYTE_SIZE]; */
{
0x80, 0xD4, 0xAA, 0xC3, 0x33, 0x54, 0xEF, 0xAC, 0x0B, 0x95, 0x20, 0x4A, 0x45, 0xE4, 0x92, 0x4D,
0x5B, 0x74, 0xF1, 0xC4, 0x2C, 0x2A, 0x5B, 0xD0, 0x50, 0x1E, 0x88, 0x46, 0x0A, 0x36, 0xC9, 0xE4,
0x79, 0x6D, 0x02, 0x0C, 0x95, 0xD1, 0x2B, 0x73, 0xA6, 0xC4, 0x9A, 0xE1, 0xE3, 0x1D, 0xB5, 0xAA
},
/* uint8_t crc[4]; */
{
0xED, 0x2D, 0xE1, 0x47
},
};
以下の情報が含まれています(big endian)。
keytype(32bit):キー種別ですが、RXの場合使用しません。
shared_key_number(32bit):RXの場合0x00000000固定です。
initial_vector(16byte):KUKのEncrypted Keyを計算するときに使用されたIVです。
encrypted_user_key(ユーザ鍵の種類による):KUKのEncrypted Keyです。
crc(4byte):keytype~encrypted_user_keyまでのCRCです。
上記のうちinitial_vector、encrypted_user_key を入力とし、ユーザ鍵のWrapped KeyをMCUに計算させることができます。
ファームウェアへの組み込み方法は、以下のような方法が考えられそうです。
Security Key Management ToolからCソースを出力しファームウェアに組み込む:攻撃者へのキーの漏洩はないものの、フラッシュのコピーによりユーザ鍵で可能な操作がすべてできる。
デバイスのプロビジョニング時にSecurity Key Management Toolからのバイナリ出力を読み込み、MCU上でユーザ鍵のWrapped Keyを計算・データフラッシュへ書き込む:プロビジョニング操作が必要な代わりに、フラッシュのコピーができない(デバイスごとのHUKで暗号化されるため)。
セキュリティを考えると、ユーザ鍵のWrapped Keyのみをデータフラッシュに保存することがよさそうです。