LoginSignup
2
3

More than 3 years have passed since last update.

デバイス内での機密情報の暗号化テスト

Last updated at Posted at 2019-09-23

はじめに

デバイス内でWifiのSSIDやパスワード、クラウド接続トークンなどを保存したいが、平文での保存が適当でない場合が考えられる。その際に如何に解読されにくくするかという実験。

AESによる暗号化

今回はAES-GCMを選択。いろいろ勉強してみたところ以下のような構成を考えた。

image.png

TLS1.2で使用される際は、ハンドシェイク後に相手と共有されるIV(初期化ベクトル)、Key(共通鍵)はどちらも生成してIVはフラッシュ上(保護なし)、KeyはATECC608Aの読み出し禁止スロットに保管。

暗号化された暗号文、その際に出るTagも併せてフラッシュ上(保護なし)に置く。
これを読みだして復号ができるかを試す。

前提条件

セキュアなIoTデバイス通信をやってみた(MbedTLS移植編-Configure)で行ったATECC608Aの初期化が完了していること。
ソースコードは下記。
https://github.com/kmwebnet/ECC608-Configure

実装

コードを実際に書いて実装を試していく。

kmwebnet/ECC608-AES-GCM-test
にてコードを公開中。

スロット5番をAES Keyとして書き込みのみ、読み出し不可の設定にする。

これを実現するため、Microchip社のテストコードのコンフィグを確認。
cryptoauthlib/python/tests/test_device.py
今回のATECC608Aでのコンフィグは下記の通りとなる。

Config Zone
バイト13:'AES_Enable': 1に設定
'SlotConfig No5': 0x36C4 → 0x00C4
ビット15-12 :Writeconfig 
ビット8-11 :WriteKey
上記を0にし書き込み可とする。

'KeyConfig No5' : 0x001C → 0x0018
ビット2-4 :Keytypeを 0b111(7)から0b110(6)に変更し、AESキーを扱うスロットとして設定する。

上記の設定をcrypto.c冒頭でも確認する。

crypto.c実装解説

crypto.hにてスロット8の416バイトの内訳を定義した。
76バイトの位置から12バイト:IV
88バイトの位置から16バイト:Tag
104バイトの位置から240バイト:暗号化データ

2つの関数を作成。
ATCA_STATUS encryptwrite(uint8_t *data, size_t length)
デバイス内へdataを書き込む
1. atcab_randomで32バイトの乱数を得る。
2. スロット5へ乱数を書き込み、AES Keyとする。
3. atcab_aes_gcm_init_randでIVの初期化を行い、スロット8へ書き込む
4. 暗号化する240バイトを16バイト単位で暗号化し、15回ループを回す。
5. atcab_aes_gcm_encrypt_finishでループ終了、Tagを取得
6. Tag,データをスロット8へ書き込み終了

ATCA_STATUS decryptread(uint8_t *data, size_t length)
デバイス内からdataを読み込む
1. デバイス内からIV,Tagを読み込む
2. atcab_aes_gcm_initでIVを設定する。
3. 復号する240バイトを16バイト単位で復号し、15回ループを回す。
4. atcab_aes_gcm_decrypt_finishでTagの確認を行い、正常なら終了。

上記の2つで、AESキーをデバイスに秘匿した状態、すなわちこのデバイスがないと復号できないデータを作成することができた。

2
3
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3