#はじめに#
2019年5月にIoTLTにてLTをさせていただきました。
その内容のフォローを記入しながら自分なりに整理していきたいと思います。
発表内容:
スタートアップIoTデバイスのセキュリティを考える
#前回までのあらすじ#
セキュアなIoTデバイス通信をやってみた(ATECC608A基本編)でPlatformioにてESP-IDFでの環境構築、さらにATECC608Aを動かすためのライブラリ cryptoauthlibをサブモジュールとして組み込み、シリアルナンバー、リビジョン番号、コンフィグ情報を表示させることができました。
#ATECC608A情報の収集#
WEB上でパブリックになっている情報を整理しながら進めていく。
cryptoauthlib/Github
すべてのAPI、サンプルソースが集約されている、何度も参照するサイト
ATECC608A製品サイト
ここのDocuments内も確認すべき情報が集まっている。
Document内の"ATECC608A Summary Datasheet"を確認すると、”complete document is available under NDA”となっている。
これだけだと詳細が不明だが、同Datasheetの最後のほうに"Compatibility"の章があり
ATECC508とのコンパチビリティについて説明がある。
翻訳すると下記の趣旨。
マイクロチップATECC508A:
ATECC608Aは、以下にリストされている機能を除いて、ATECC508Aデバイスと完全に互換性があるように設計されています。 ATECC608Aが正しく設定されていれば、ATECC508A用に書かれたソフトウェアは、必要な変更を加えることなくATECC608Aと連携するはずです。
注:ATECC608Aの構成ゾーンのほとんどのエレメントは、位置と値の両方がATECC508Aと同じです。 ただし、LastKeyUseフィールドに格納されていた初期値は、このドキュメントに記載されている可能性があるこれらのバイトの新しい定義に準拠するように変更する必要があります。
そのフィールドには、単調カウンタを介してATECC608AでサポートされているSlot 15限定使用機能の初期カウントが含まれていました。
■ATECC508Aに対するATECC608Aの新機能
•安全なブート機能、IO暗号化および認証付き
•PRF、HKDF、AESをサポートするKDFコマンド
•暗号化/復号化を含むAESコマンド
•AESのGCM AEADモード用GFM計算機能
•NIST SP800-90 A / B / C乱数発生器をアップデート
•コンテキスト保存/復元を使用した柔軟なSHA / HMACコマンド
•SHAコマンドの実行時間が大幅に短縮
•デバイス転送を防止するための揮発キー
•配送中にプログラムされたデバイスを保護するためのトランスポートキーロック
•カウンタリミットマッチ機能
•ECDHおよびKDFでもサポートされている、SRAMでの一時キー生成
•MACを使用してコマンド出力を検証できることを確認
•ECDH用の暗号化された出力
•セルフテストコマンド、オプションの自動電源投入時セルフテストを追加
•組み込みX.509証明書キー検証用の未整列の公開キー
•実行時間の増加に伴うオプションの電力削減
•データ(シークレット)ゾーンロック後のプログラム可能なI2Cアドレス
■ATECC508Aに対しATECC608Aで除去された機能
•HMACコマンドが削除され、より強力なSHAコマンドに置き換えられました
•OTP消費モードが廃止され、読み取り専用になりました
•UpdateExtraの関連Selector機能とともにPauseコマンドが削除されました
•スロット15の特別限定使用を廃止、標準の単調カウンタ限定使用に置き換え
•SHAコマンドはダイジェスト計算中にTempKeyを使用しなくなり、TempKeyの結果はSHA操作を通じて変わらなくなります。 ただし、TempKeyを使用してHMAC_StartのSHAを初期化したり、最終ダイジェストを保存したりすることはできます。
機能追加があるが、大幅な変更はないようだ。
ATECC508であれば、Complete DataSheetが下記で参照できるため、こちらを
参照することにする。
ATECC508A CryptoAuthentication Device Complete Data Sheet
#内部ストレージ概要#
ATECC508A CryptoAuthentication Device Complete Data Sheetによれば、下記の通りデータを保存する領域がある。
2.1 EEPROMデータゾーン
データゾーンは16のスロットに分割されており、アクセス制限は個別にプログラム可能です。 すべてのスロットを秘密鍵、秘密鍵、またはユーザーデータに使用できますが、スロット8〜15のみがECC公開鍵またはECDSA証明書/署名を格納するのに十分な大きさです。 スロットが秘密鍵または秘密鍵に使用されている場合、特定のアルゴリズムで必要とされていない余分なメモリは通常使用できません。 次の表に、各グループのスロットの一般的な用途と、そのグループ内のスロットの特殊な特性を示します。
ECC公開鍵または秘密鍵を含むデータスロットは、「セクションECC鍵のフォーマット」に従ってフォーマットする必要があります。 デバイスは、KeyConfigのKeyTypeフィールドとPubInfoフィールドを使用して、スロットに格納されている内容を判別します。秘密鍵は、いかなる状況においてもデバイスから読み取ることはできません。 ECCキースロットの内容は、次のように検証されない限り、ECCコマンドで使用できない可能性があります。
•ECC秘密鍵: スロットで最初のPrivWriteまたはGenKey(Create)コマンドを実行する前は、秘密鍵は無効です。 PrivWriteコマンドが開始されたが、完了前に電源が遮断された場合も、キーは無効になる可能性があります。
•ECC公開鍵: KeyConfigのPubInfoビットが1の場合は、入力署名とECC Verifyコマンドを使用してキーを検証する必要があります。そのビットがゼロの場合、ECCの使用はキー検証操作に依存しません。これらの鍵は、スロット8から15にのみ保管できます。この機能はオプションです。
わからない単語が多く出てくるが、まとめると、
1、データゾーンのスロットが15個用意されている。
2、0~7はプライベート用途および秘密鍵用に使える36バイトの容量を持っている。
3、8はデータとして使える416バイトの領域
4、9~14は72バイトづつの公開鍵、もしくは署名が入る領域
5、15は先ほどのATECC608Aで機能が削除されているので9~14と同様に使える。
6、ECC鍵としてスロットを使用する場合、Keyconfigにて設定をする必要がある。
ということらしい。一般的な証明書がおよそ1KBということを考えると、とても証明書を丸ごと保存する領域はないことがわかる。
#主要なコマンド#
ATECC508A CryptoAuthentication Device Complete Data Sheetから主要コマンドを抜粋する。
9.7 GenKeyコマンド
GenKeyコマンドは、以下の3つの操作のうち1つ以上を実行します。
1,秘密鍵の作成 新しいランダム秘密鍵を作成し、その鍵をKeyIDパラメーターで指定されたスロットに書き込みます。 EEPROM RNGシードは、この電源の再投入でまだ更新されていない場合、このコマンドの実行前に自動的に更新されます。
2,公開鍵の計算 KeyIDパラメータで定義されたスロットに格納されている秘密鍵に基づいてECC公開鍵を生成します。 このモードのコマンドは、それを再生成するのに必要な時間を犠牲にしてデバイスに公開鍵を格納することを回避するために使用され得る。
3,ダイジェスト計算 GenKeyは、KeyIDパラメータによって参照される公開鍵をTempKeyに格納されている現在の値と組み合わせて、結果のメッセージのSHA-256ダイジェストを計算し、そのダイジェストをTempKeyに戻すこともできます。 このダイジェストは、内部署名のメッセージとして、またはMAC計算のコンポーネントとして使用できます。 TempKeyはダイジェスト計算の前に有効でなければなりません。 KeyConfig.ReqRandomが設定されている場合、TempKeyは内部RNGを使用して作成されているはずです。
9.14 PrivWriteコマンド
PrivWriteコマンドは、外部で生成されたECC秘密鍵をデバイスに書き込むために使用されます。
注:最高のセキュリティを確保するために、マイクロチップ社はPrivWriteコマンドを使用しないことと、秘密鍵をGenKey(Create)コマンドを使用してRNGから内部的に生成することをお勧めします。
9.16 Readコマンド
Readコマンドは、デバイスのメモリゾーンの1つからワード(4バイト1ワードまたは32バイトの8ワードブロック)を読み取ります。
9.18 Signコマンド
Signコマンドは、ECDSAアルゴリズムを使用して署名を生成します。 KeyIDで指定されたスロット内のECC秘密鍵を使用して署名が生成されます。
9.20 Verifyコマンド
VerifyコマンドはECDSA 署名を取り、それが与えられたメッセージと公開鍵から正しく生成されたことを検証します。
9.21 Writeコマンド
Writeコマンドは、1つの4バイトワードまたは8バイトの32バイトブロックをデバイスのいずれかのEEPROMゾーンに書き込みます。
上記から、以下の通り整理できる。
1、秘密鍵の取り扱いは、genkeyコマンドで内部で秘密鍵を生成する方法、またPrivwriteで外部で作成した秘密鍵をデバイスへ書き込む2つに対応している。
しかし、内部で秘密鍵を生成したほうが安全である、と推薦している。
2、デバイスへの読み書きコマンドと合わせて、署名、検証のコマンドが用意されている。
#証明書の保管の仕方#
ATECC508A CryptoAuthentication Device Complete Data Sheetのうち、証明書定義についての説明を翻訳。
2.1.1 証明書ストレージ:
デバイス内の完全なX.509証明書に必要なストレージ容量は、複数のEEPROMメモリスロットを急速に使い果たす可能性があります。実際のアプリケーションによっては、証明書の保存にこれらのスロットを使用することが望ましい場合もあれば、望ましくない場合もあります。
これらのメモリ制限のため、Microchip社は、最小限の情報から完全なX.509証明書を再構築することを可能にするエンコーディングを定義しました。 ホストシステムは実際には完全なX.509証明書を再構築する責任がありますが、これを行う方法はエンコードされた証明書に格納されているデータによって決まります。 特定のシステムのすべてのデバイスに共通のデータは、ホストシステムに簡単に保存できます。
他のデータは、装置に既に格納されているデータから容易に計算または抽出することができる。
表2-4に、X.509証明書に格納されているデータの種類と、1つの72バイトスロットに収まるようにエンコードする方法を示します。
まとめ:
この表から、デバイス証明書と合わせて署名者証明書(中間CA)も保存、取り扱いを行うことが読み取れる。
証明書の要素を分解してデバイス内に保存することがわかる。
#次回#
実際にサンプルコードを基に実装を行っていきながら、コンフィグの意味、証明書の保存の仕方を把握していく。