M5Stack Core2 for AWS のセキュリティチップ(ATECC608A)から真性乱数を得る

#M5Stack Core2 for AWSについて
Amazonのクラウドサービスの、Amazon Web Service (AWS)にAWS IoTとして接続させるようにカスタマイズされた、"M5Stack Core2 for AWS"が2020年12月に発売されました。
スイッチサイエンスで発売されたらすぐに完売されるぐらい人気商品で、最近(2021/2)はやっと安定供給されるようになってきたようです。
この製品は、M5Stackの次世代版のCore2に専用のM5GO Bottom2(M5Stack Core2専用バッテリーボトム)を加えたものとなっているとのことです。このM5GO Bottom2には、AWSと安全にアクセスできるための、Microchip社 ATECC608A Trust&GOセキュアエレメントが内蔵されています。
それ以外は、普通のM5Stack Core2の様です。

今回は、M5Stack Core2 for AWSを利用して、あまり接点のなかったセキュア・エレメントに触れることで、IoTセキュリティの基礎技術であるRoT(Root of Trust)＋セキュリティ機能の内の真性乱数発生機能を動かしてみます。

なお、AWSの接続は本家のチュートリアル( https://edukit.workshop.aws/en/getting-started.html )を参照していただくこととして、ここではオーソドックスなArduino IDEを使って直接ATECC608Aを操作していきます。

##M5Stack Core2 for AWS概要
M5Stack Core2 for AWSは、ESP32と言ういわゆる中華Wi-Fiチップを使ったIoTガジェットの最新版です。
ESP32は、リコンフィギャラブルプロセッサIPのテンシリカ社 Xtensaを使ったWi-Fi / Bluetoothモジュールで、PoCだけでなく中華ガジェットやIoT機器に広く使われています。
元々はモジュールやPoC用のボードで使われていて、Arduino IDEやUIFlowを使ったMicroPythonとか開発環境が提供されています。

M5Stack Core2 for AWSでは特に、VS Codeを上のPlatformIOで環境が作られており、Arduino IDEでの利用は若干邪道なのかもしれません。

本ページの動作を確認するために、Arduino IDEのインストール、設定、M5Core2のボード環境設定はすでにやっていることが前提ですので、ご注意をお願いします。


<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33155/8d4093f7-acd4-f967-27f1-4440b5926575.png"> <img width="400" src="https://docs.m5stack.com/assets/img/product_pics/core/core2_aws/core2_aws_02.webp">

 - ESP32-D0WDQ6-V3マイコン搭載 (Xtensa32ビットLX6デュアルコア, 最大240 MHz)
 - 2.4 GHz Wi-Fi、Bluetooth 4.2 BR/EDR、BLE
 - オンボードで8 MB PSRAMと16 MBフラッシュ
 - 2.0インチの静電容量性タッチスクリーン
 - 振動モーター内蔵
 - オンボードRTCモジュール内蔵
 - microSDカードスロットを搭載 (最大16 GBのmicroSDカードが利用可能)
 - スピーカー内蔵
 - 6軸IMU（慣性計測ユニット）兼温度センサ (MPU6886)
 - デジタルマイク(SPM1423)
 - 10個のRGB LED (SK6812)
 - リチウム電池内蔵(500 mAh)
 - 筐体背面に磁石内蔵 (冷蔵庫とかに貼って使える)
 
IoTガジェットとしては至れり尽くせりで、他にセンサーをつなげたい場合は拡張端子(GROVE? I2C)で接続できるようです。


#Microchip社 ATECC608A Trust&GOセキュアエレメント概要
Microchip社が販売している、IoTに特化したセキュア・エレメント(セキュリティの為の部品)です。PCのマザーボードのセキュリティチップのTPMのIoT版とも言えます。
IoTが広がってきて、IoTをコントロールするデバイスにもセキュリティ機能が含まれていたりするのですが、残念ながらしっかりしたセキュリティが実装されたSoCは、スマートフォンのチップぐらいで、それ以外はいわゆる「なんちゃってセキュリティ」という感じである状況を打開するために作られたChipだと思われます。
メインの機能は鍵管理で、認証、暗号通信のための鍵データを扱うことと、いくらかの暗号処理(TRNG, Hash, 共通鍵暗号、公開鍵暗号)を持っており、I2Cでホストと通信します

ただ、文章で説明するのは簡単なのですが、Chipの仕様書を観てもなかなか機能、使い方、とかわかりにくいです。
Chipの機能ブロック図とかが開示されていなくて、機能、構成、構造は仕様書の文章から読み解かないといけないというのもわかりにくい理由の1つのかもしれません。

##ATECC608A機能概要
ATECC608Aは一通りのセキュリティ機能を持っています。いわゆるRoTとセキュリティファンクションを備えたチップと言えます。単価100円以下のChipなのに大したモノです。

* 鍵管理 (最大16個の鍵を記録できる。保護機能付き)
* 公開鍵暗号(楕円暗号)、ECDSA署名プロトコルを使った署名、認証機能
* 共通鍵暗号(AES128)、ハッシュ関数(SHA256)対応
* TRNG(真性乱数)対応(NIST 800-90A、800-90B、800-90C要件対応)

おそらくEEPROMを持ったマイコンで構成されているだろうと予想しています。
鍵管理のメモリの使い方が不可逆(元に戻せない)設定もあり、勝手アクセスはちょっと気を付ける必要があります。


#Arduino IDE環境下でのATECC608Aサポート
現時点(2021/2/18)では、M5Stack Core2 for AWS向けの完璧なライブラリはArduinoでは提供されていないようです。
今回の対象のセキュア・エレメント ATECC608Aは8pinの小さなChipにもかかわらず、結構複雑な機能が実装されており、それを使うには、データシートやアプリケーションノート系の情報を熟知しないといけないので、I2C信号からの操作は相当時間がかかってしまいます。
そこで、今回は、すでにオリジナルのArduino Uno等に接続することを想定して販売されている、SparkFun Cryptographic Co-processor Breakout ATECC508A (Qwiic)用に提供されているライブラリを利用してアクセスしてみることとします。
<img width="400" src="https://camo.githubusercontent.com/f08d36efcbcefcec5813e188945aadea636edbff53b6422244c8bf25ac172953/68747470733a2f2f63646e2e737061726b66756e2e636f6d2f6173736574732f70617274732f312f342f312f362f392f31353537332d537061726b46756e5f43727970746f677261706869635f436f2d50726f636573736f725f427265616b6f75745f2d5f4154454343353038415f5f51776969635f2d30312e6a7067">

## SparkFun_ATECCX08a_Arduino_Library
このライブラリは、ここ( https://github.com/sparkfun/SparkFun_ATECCX08a_Arduino_Library )にあります。
Arduino IDEへのライブラリの追加方法は、他のネットリンクで調べてもらえればと思います。
(zipファイルダウンロードして、　Arduino IDEのメニューからライブラリ追加し、Arduino IDEを再起動させます。)
ライブラリを追加すると、ファイル→スケッチ例から、"SparkFun_ATECCX08a_Arduino_Library"が見えます。
今回は、その中の"Example5 Random"を動かしてみることとします。

# 真性乱数の取得
セキュア・エレメントの利用は、鍵管理が基本で、鍵データを作ったら書き換えられないようにロックして、暗号化、認証を使うということで利用される様です。
M5Stack Core2 for AWSも、その流れでAWSにM5Stack Core2 for AWSを登録してAWS連携ができるようになると思われますので、今回の不要な操作でAWS接続が阻害されるといろいろ困りますので、鍵データの関わらない機能として、真性乱数機能にアクセスすることとしました。

SparkFun_ATECCX08a_Arduino_LibraryのExampleも、最初のExample1のConfigurationを済ましてから、認証や暗号操作の確認をする手順となっている様です。暗号化するには鍵情報のLockが必要であるような感じなのですが、少なくとも真性乱数は鍵情報を使わないので、ATECC608A機能を確かめる用途には最適だと考えました。

まず、Arduino IDEのメニューのファイル→スケッチ例→"SparkFun_ATECCX08a_Arduino_Library"→"Example5 Random"を選択し、サンプルソースファイルを開きます。
この際、ご自身のフォルダに一旦書込を行うことをお勧めします。

このソースコードは、SparkFun社のボードとかArduino Unoとかに特化している様で、M5Stack Core2 for AWSでは動かない。そこでM5Stack Core2 for AWS用設定を追加しました。

## M5Stack Core2の設定
M5Stackとして稼動させる際に、特有の設定があります。

```C++:Example5_Random.ino(途中)
#include <M5Core2.h>
...
void setup() {
  M5.begin(true, true, true, true);
  ...
```


## I2Cアドレス、ポートの設定
M5Stack Core2 for AWSのATECC608Aは、内部のI2C端子に接続されています。Arduinoでは、Wireでアクセスできます。また、I2Cはデバイス毎に固有のアドレスを持っており、私のデバイスは0x35のアドレスでした(これは、別途I2Cスキャンプログラムで探しました。)。
Example5 Randomでは、最初にateccの設定用Class呼びだしがあるので、その引数にM5Stack Core2 for AWS特化情報を追加します。

```C++:Example5_Random.ino(途中)
  /* 元 */ if (atecc.begin() == true)
  /* 新 */ if (atecc.begin(0x35, Wire, Serial) == true)
```

## ATECC608Aメモリのロック状況のチェック

```C++:Example5_Random.ino(途中)
  // check for configuration
  if (!(atecc.configLockStatus && atecc.dataOTPLockStatus && atecc.slot0LockStatus))
  {
    Serial.print("Device not configured. Please use the configuration sketch.");
    // while (1); // stall out forever. /* コメント化して無限ループに入らないようにする */
  }

```

以上の設定で、Example5が上手く動くようになります。

##実行例
AWSの設定がされていない状態で稼動させたので、Data Slot 0がLockされていない状態ですが、TRNG機能は正常に稼動している様です。

```
15:59:31.068 -> Successful wakeUp(). I2C connections are good.
15:59:31.105 -> 
15:59:31.105 -> Serial Number: 	XXXXXXXXXXXXXXXXXX
15:59:31.105 -> Rev Number: 	00006002
15:59:31.105 -> Config Zone: 	Locked
15:59:31.105 -> Data/OTP Zone: 	Locked
15:59:31.105 -> Data Slot 0: 	NOT Locked
15:59:31.105 -> 
15:59:31.105 -> Device not configured. Please use the configuration sketch.
15:59:31.139 -> Random number: 15
15:59:31.173 -> Random number2: 174
15:59:31.211 -> Random Byte: 0xD2
15:59:31.211 -> Random Int: 49987
15:59:31.249 -> Random Long: -173161879
15:59:31.286 -> atecc.random32Bytes[32]: F25D4D167265D523823F693DA84DBCB8863EE2E6F1986D4528DBD2FB9D93550F
```
確認のためにもう一度実行してみます。

```
16:14:49.952 -> Random number: 95
16:14:49.986 -> Random number2: 175
16:14:50.021 -> Random Byte: 0x34
16:14:50.055 -> Random Int: 62994
16:14:50.089 -> Random Long: -773678228
16:14:50.122 -> atecc.random32Bytes[32]: F933B9E8871EC654FCF3DE58B5EB535C2962C8DEBE1FD374A6026BDFB22A6A43
```
乱数値なので、アクセスする毎に異なる値が表示されます。


その他の動作確認は、AWSの登録を済ませてから進めようと思っています。