# MAM E2EE Plan
###### tags: `mam`
## requirement
1. 上下 message 有相依性關係
2. 有前面的訊息能驗證下一筆訊息是來自同樣的來源
3. 中間溝通的對稱式加密,key 要能夠一直變換
* ## Proposal
* 用 hardware identity 當作 key material,進行 HKDF 運算,產生 AES key
* 確保中間加密的 AES key 可以一直產生且不可藉由上一個 key 去推斷下一個 key
* `AES key = HKDF(hardware_identity, MAC_[n-1])`
* `MAC_[n-1]` 被當成 HKDF 的 `info`
* 每筆訊息都用 AES 進行加密
* 每一筆訊息都用 MAC 去確保 data integrity
* 確保訊息沒有被竄改
* `h = Hash(MAC_[n-1] | MAC_[n])`,對 h 以 ECDSA key (或是其他非對稱式簽名)進行簽名
* 確保上下 message 之間的連續性(是來自同樣的來源)
## Change Key
若 AES key 有可能有被破解的問題,或者因為其他理由需要換, endpoint 可以透過 subscriber 的 ECC 公鑰進行加密,傳送下一個 key material 給個別的 subscriber
## Security Level Comparison


## Workflow
```graphviz
digraph {
start[shape="circle", style="", label="start"];
hw[shape="parallelogram", style="", label="fetch hardware info"];
msg_exist[shape="diamond", style="", label="Whether this is the first message"];
MAC_last[shape="parallelogram", style="", label="Get MAC of last message Mac_{n - 1}"];
init_info[shape="parallelogram", style="", label="Use initialization information"];
iv[shape="box", style="", label="Set as IV"];
HKDF[shape="box", style=""]
plaintext[shape="parallelogram", style=""];
AES[shape="box", style="", label="AES encryption"];
HMAC[shape="box", style=""];
concat_sign[shape="box", style="", label="concatenate: MAC_n + Mac_{n-1}"];
sign[shape="box", style="", label="Signed with ECDSA"];
concat_res[shape="box", style="", label="concatenate: signed MAC + cipher"];
end[shape="circle", style="", label="end"];
{rank=same; AES->plaintext->HMAC[style=invis];}
start->hw->msg_exist
msg_exist->init_info[label="yes"]
msg_exist->MAC_last[label="no"]
init_info->iv
MAC_last->iv
iv->HKDF
iv->sign
plaintext->AES
HKDF->AES[label="AES Key"]
HKDF->HMAC[label="AES Key"]
plaintext->HMAC
HMAC->concat_sign[label="MAC_n"]
concat_sign->sign
AES->concat_res[label="ciphertext"]
sign->concat_res[label="signed MAC"]
concat_res->end
}
```
## High level workflow
Here let's take sensor as example. A sensor runs with low-level devices keeps sending message through MAM.
`local encryption` should be taken on sensor. This step ensures the proxy server (tangle-accelerator) can't tamper the message sent by sensor.
Once `local encryption` has been taken on sensor, then the sensor can transfer the encrypted cipher to proxy server, which will publish the cipher on MAM channel.
Each channel owner has its own user ID which mapping to corresponding channel seed on a certain tangle-accelerator. With the following request format, a sensor can send message through MAM API.
Once MAM publishing request has been issued, user can't modify or cancel sending it. The structure of MAM messages is a linked-list like structure. Therefore, for a MAM message subscriber, once the subscriber fetch all the message under the queried channel, then a channal ID which represents the ID of next channel will be returned. If the user want to fetch the message in the next channel, then the user can take this ID as the query argument of the next API call.
```graphviz
digraph {
"Input Data"[shape="box", style=rounded];
"local encryption"[shape="diamond", style=rounded]
"Packet to MAM API Format"[shape="box", style=rounded];
"Process MAM request"[shape="diamond", style=rounded]
"Message ID on Blockchain"[shape="box", style=rounded];
"endpoint"[shape="box", style=filled];
"proxy server"[shape="box", style=filled];
subgraph a {
label="Subgraph A";
rank="same"
"local encryption" -> "endpoint"[dir=both, arrowhead=none, arrowtail=n];
}
subgraph b {
label="Subgraph A";
rank="same"
"Process MAM request"->"proxy server"[dir=both, arrowhead=none, arrowtail=n];
}
"Input Data"->"local encryption"
"local encryption"->"Packet to MAM API Format"[label="{\"sign\":\"<signed>\",\"cipher\":\"<cipher>\"}"];
"Packet to MAM API Format"->"Process MAM request"[label="{\"x-api-key\": \"<token>\",\l \"data\": {\l \"seed\": \"<seed>\",\l \"messag\": \"{\"sign\":\"<signed>\",\"cipher\":\"<cipher>\"}\"\"\l },\l \"protocol\": \"MAM_V1\"\l }\l"];
"Process MAM request"->"Message ID on Blockchain"
}
```
### Sample Input/Output in Local encryption
In this process AES and ECDSA will be taken. The security level of all these process can be chosen customizedly. The digest (actualy it is the result of HMAC) the last message will be signed with the the digest of last message.
#### Input
```json
{"consumption":"12kWh"}
```
#### Output
```json
{
"sign": "106859e92508b76d949432edb00c26284da7e458ce111f5d39ef5df2ae2e26b9457e0bdf7caf9896c669ecce3c1bf12d615ccc4c7b9fe34f995b4cb73929782b",
"cipher": "00000000000000000000000000000000dbb88e1f9e6d46753650d172aaa8905abb784f0427b29799c263543311c0a708"
}
```
### Request
```json
{
"x-api-key": "3bff60110c9f0e40628031b16dfefe2eb45a6b0c2237b49ef5109f9aa8eb19a8",
"data": {
"seed": "QBFXQETKSHDYPFUDO9ILVCAVQIXOHXKCECZYFLPBNVIX9JUXQZJE9URQEEUWPWYZOIACTCGZX9IDIODCA",
"message": "{\"sign\": \"106859e92508b76d949432edb00c26284da7e458ce111f5d39ef5df2ae2e26b9457e0bdf7caf9896c669ecce3c1bf12d615ccc4c7b9fe34f995b4cb73929782b\",\"cipher\": \"00000000000000000000000000000000dbb88e1f9e6d46753650d172aaa8905abb784f0427b29799c263543311c0a708\"}"
},
"protocol": "MAM_V1"
}
```
### Response
#### send message
Sample Successful Response
```json
{
"bundle_hash": "KDDZYLEUAFQGNZRU9GIXCW9GDSVWQDEXYHEBUKPHNVGHTHIG9INQALJSBVPHSBLAOKAGYZHQEKKXDVINA",
"chid": "9UISEXBYMDSXOHRRWBHAFOI9TLEZZCOQXTQO9KVBDGGHCP9ITEOQRAGUKXWFTEWLWMUKFLN9IWFFYCXZM",
"msg_id": "IONONZOXVGTNGVEOCXPUI"
}
```
### curl example
```shell
curl http://node.deviceproof.org:5566/mam/recv \
-X POST \
-H 'Content-Type: application/json' \
-d '{"data_id": {"chid": "9UISEXBYMDSXOHRRWBHAFOI9TLEZZCOQXTQO9KVBDGGHCP9ITEOQRAGUKXWFTEWLWMUKFLN9IWFFYCXZM"},"protocol": "MAM_V1"
}'
```
##### Error
For the condition that blockchain full node met some issues, or blockchain network met problems, instead of the data of sent message, an uuid will be returned.
Sample Response in Full Node Error
```json
{
"uuid": "123e4567-e89b-12d3-a456-426655440000",
"address": "THIS9IS9AN9ADDRESS9USED9BY9TAGNLEACCELERATOR9999999999999999999999999999999999999"
}
```
### Read message
Recv MAM message
#### Receive MAM message
##### Request
```json
{
"data_id": {
"chid": "9UISEXBYMDSXOHRRWBHAFOI9TLEZZCOQXTQO9KVBDGGHCP9ITEOQRAGUKXWFTEWLWMUKFLN9IWFFYCXZM"
},
"protocol": "MAM_V1"
}
```
##### Response
```json
{
"payload": ["This is message No1", "This is message No2", "This is message No3"],
"chid1": "THIS9IS9AN9ADDRESS9USED9BY9TAGNLEACCELERATOR9999999999999999999999999999999999999"
}
```
#### Verify Message
```graphviz
digraph {
"input"[shape="diamond", style=rounded, label="input data"]
"decrypt"[shape="box", style=rounded, label="Decrypt ciphertext\n"]
"plaintext"[shape="diamond", style=rounded, label="plaintext"]
"cur_hash"[shape="box", style=rounded, label="Check if this message contains\ncorrect hash of current message\n"]
"last_hash"[shape="box", style=rounded, label="Check if this message contains\ncorrect hash of last message\n"]
"hash_sig"[shape="box", style=rounded, label="Check if the signature of the\nconcancated hash is correct\n"]
"result"[shape="box", style=rounded, label="Final result\nTrue or False?"]
"input"->"decrypt"->plaintext
"plaintext"->"cur_hash";
"plaintext"->"last_hash"
"cur_hash"->"hash_sig"
"last_hash"->"hash_sig"
hash_sig->result
}
```
### security
The security level with wished security bit is possible, since we apply HKDF in our encryption framework. However, user should be aware of giving long enough Key Material to generate AES keys. For a certain security bits, user should choose the corresponding asymmetric key pairs which meet the AES security bits.
## Reference
[HKDF link](https://en.wikipedia.org/wiki/HKDF)