OPTEE之安全存储详解
文章目錄
- 安全存儲是什么?
- 二、安全存儲相關技術點
- 1.加載dirf.db文件
- 2. dirf.db文件和安全存儲文件的格式
- 2.1 安全文件的三個區域
- 2.2 重要結構體的關系框圖
- 2.3 FEK和IV介紹
- 3. 安全的基本操作
- 3.1 安全文件的創建
- 3.2 安全文件的讀取
- 3.3 安全文件的寫入
- 4. 安全存儲中的加密解密
- 4.1 數據結構的組成與作用
- 4.2 元數據的加密
- 4.3 數據塊數據的加密
- 總結
安全存儲是什么?
OP-TEE的安全存儲功能是OP-TEE為用戶提供的安全存儲機制。
用戶可使用安全存儲功能來保存敏感數據、密鑰等信息。
使用OP-TEE安全存儲功能保存數據時,OP-TEE會對需要被保存的數據進行加密,且每次更新安全文件時所用的加密密鑰都會使用隨機數重新生成,用戶只要調用GP標準中定義的安全存儲相關接口就能使用OP-TEE的安全存儲功能對私有數據進行保護。
需要被保護的數據被OP-TEE加密后會被保存到REE側的文件系統、EMMC的RPMB分區或數據庫中,至于具體需要將加密后的數據保存到哪里則由芯片提供商決定。
安全存儲功能可提供一個安全的存儲環境,安全文件中數據的加解密過程都在OP-TEE中完成,且加解密密鑰的生成也是在OP-TEE中進行的,這樣就能保證數據的安全性。
二、安全存儲相關技術點
1.加載dirf.db文件
我們以打開安全文件為例,跟蹤學習一下OPTEE安全存儲相關的調用流程。
@tee_ree_fs.c
提供了基本的文件操作接口
我們看一下其中的open函數ree_fs_open
static TEE_Result ree_fs_open(struct tee_pobj *po, size_t *size,struct tee_file_handle **fh) { ...res = get_dirh(&dirh);res = ree_fs_open_primitive(false, dfh.hash, &po->uuid, &dfh, fh);... }通過ree_fs_dirh_refcount全局變量 來控制是創建dirf.db文件,還是打開dirf.db文件
static TEE_Result get_dirh(struct tee_fs_dirfile_dirh **dirh) {if (!ree_fs_dirh) {TEE_Result res = open_dirh(&ree_fs_dirh);if (res) {*dirh = NULL;return res;}}ree_fs_dirh_refcount++;assert(ree_fs_dirh);assert(ree_fs_dirh_refcount);*dirh = ree_fs_dirh;return TEE_SUCCESS; }@fs_dirfile.c
TEE_Result tee_fs_dirfile_open(bool create, uint8_t *hash,const struct tee_fs_dirfile_operations *fops,struct tee_fs_dirfile_dirh **dirh_ret) { ...dirh->fops = fops;res = fops->open(create, hash, NULL, NULL, &dirh->fh); ... }static const struct tee_fs_dirfile_operations ree_dirf_ops = {.open = ree_fs_open_primitive,.close = ree_fs_close_primitive,.read = ree_fs_read_primitive,.write = ree_fs_write_primitive,.commit_writes = ree_dirf_commit_writes, };ree_fs_open_primitive函數
static TEE_Result ree_fs_open_primitive(bool create, uint8_t *hash,const TEE_UUID *uuid,struct tee_fs_dirfile_fileh *dfh,struct tee_file_handle **fh) {struct tee_fs_fd *fdp;fdp = calloc(1, sizeof(struct tee_fs_fd));fdp->fd = -1;fdp->uuid = uuid;if (create)res = tee_fs_rpc_create_dfh(OPTEE_RPC_CMD_FS,dfh, &fdp->fd);elseres = tee_fs_rpc_open_dfh(OPTEE_RPC_CMD_FS, dfh, &fdp->fd);res = tee_fs_htree_open(create, hash, uuid, &ree_fs_storage_ops,fdp, &fdp->ht); }@fs_htree.c
讀文件時,主要是通過如下代碼實現的,其中有校驗的部分,請查看如下代碼注釋部分。
其中verify_root函數內容如下:
static TEE_Result verify_root(struct tee_fs_htree *ht) {TEE_Result res;void *ctx;res = tee_fs_fek_crypt(ht->uuid, TEE_MODE_DECRYPT, ht->head.enc_fek,sizeof(ht->fek), ht->fek);if (res != TEE_SUCCESS)return res;res = authenc_init(&ctx, TEE_MODE_DECRYPT, ht, NULL, sizeof(ht->imeta));if (res != TEE_SUCCESS)return res;return authenc_decrypt_final(ctx, ht->head.tag, ht->head.imeta,sizeof(ht->imeta), &ht->imeta); }=============================================================================================
2. dirf.db文件和安全存儲文件的格式
在了解了基本的流程后,我們接下來來扣一下細節,查看一下文件的格式以及結構體的定義等。
2.1 安全文件的三個區域
使用安全存儲功能生成的文件都會使用相同的格式被保存,而且dirf.db文件與安全文件的格式也相同。
安全文件中的內容分為三個區域,分別用于保存文件頭、結點、數據,文件的內容。
描述如下:
有三個重要的結構體:
tee_fs_htree_node_image:用于保存文件的節點node信息,通過節點可找到對應文件的頭部或數據塊信息;tee_fs_htree_image:用于保存安全文件的頭部數據,從頭部數據中可獲取安全文件的加密密鑰和加密頭部時使用的IV值; tee_fs_fd:安全存儲操作時使用的重要結構體,存放對文件操作時使用的fd、dir、TA的UUID等信息。
結構體字段的定義如下:
@core/include/tee/fs_htree.h
2.2 重要結構體的關系框圖
這些重要的結構體的關系框圖如下:
其中tee_fs_htree_storage 結構體定義如下,包含了讀寫RPC調用的函數指針。
2.3 FEK和IV介紹
有幾個重要的概念 要先介紹一下:
1. SSKSecure Storage Key 安全存儲密鑰,在每臺設備中都不一樣(一般和chipID進行綁定)。2. TSKTrustedApplication Storage Key 可信應用的存儲密鑰,TSK是使用SSK作為密鑰對TA的UUID經HMAC運算得到的。3. FEKFile Encryption Key 是安全存儲功能用于對數據進行加密時使用的AES密鑰。使用場景:
FEK + IV值 ==》加密密文數據
這幾個KEY的的使用關系:
ChipID + HUK ==》 HMAC運算 ==》 SSK SSK + UUID ==》 HMAC運算 ==》 TSK TSK + RANDOM ==》 AES_CBC ==》 Encryption_FEK小結:總的來說OPTEE這么設計,主要是想利用兩個文件來完成校驗功能,一個是加密的安全文件,一個是全局的dirf.db文件。
每次想操作安全文件時,會先從dirf.db中找關鍵信息,同時做加解密和校驗工作,來保證數據的安全性。
=============================================================================================
3. 安全的基本操作
了解了以上基本概述后,我們接下來看一下詳細的安全文件的操作,看下是如何處理安全文件的數據的。
因為OPTEE中沒有文件系統的功能,需要借助tee_supplicant守護進程來完成訪問文件系統的工作。
讀寫安全文件也是類似的過程,TA發送RPC請求給tee_supplicant,tee_supplicant完成參數的解析和數據操作。
3.1 安全文件的創建
dirf.db文件的創建
在創建dirf.db文件過程中會產生一個隨機數作為FEK,且在調用update_root函數時會產生另外一個隨機數作為加密FEK的IV值并保存到head.iv中。每次文件的更新時,該IV值都會被新的隨機數替代。
安全文件的創建
在TA中調用TEE_CreatePersistentObject接口時會創建安全文件。在創建安全文件時會初始化安全文件的數據區域。
安全文件創建完成之后,會將初始化數據加密后寫入到安全文件中,然后更新整個安全文件的tee_fs_htree_node_image區域以及保存在文件頭的tee_fs_htree_image區域,到此安全文件創建就已完畢。
為后續能夠通過dirf.db文件找到該安全文件,則還需要更新dirf. db文件的內容,主要是更新dirf.db文件數據區域中的dirfile_entry數據。
3.2 安全文件的讀取
TA對安全文件進行讀寫操作是通過調用TEE_ReadObjectData和TEE_WriteObjectData函數來實現的。這兩個函數的執行最終會進入OP-TEE的內核空間中。
在OP-TEE內核空間調用對應的讀寫接口syscall_storage_obj_read和syscall_storage_obj_write函數來完成對安全文件中數據的讀寫操作。
看一下相關的代碼:
@tee/tee_svc_storage.c
檢查訪問權限,調用
@tee_ree_fs.c
static TEE_Result ree_fs_read(struct tee_file_handle *fh, size_t pos,void *buf, size_t *len) {TEE_Result res;mutex_lock(&ree_fs_mutex);res = ree_fs_read_primitive(fh, pos, buf, len);mutex_unlock(&ree_fs_mutex);return res; }static TEE_Result ree_fs_read_primitive(struct tee_file_handle *fh, size_t pos,void *buf, size_t *len) { ...struct tee_fs_htree_meta *meta = tee_fs_htree_get_meta(fdp->ht);#計算安全文件數據區域中的blockstart_block_num = pos_to_block_num(pos);end_block_num = pos_to_block_num(pos + remain_bytes - 1);block = get_tmp_block();#循環讀取數據while (start_block_num <= end_block_num) {size_t offset = pos % BLOCK_SIZE;size_t size_to_read = MIN(remain_bytes, (size_t)BLOCK_SIZE);if (size_to_read + offset > BLOCK_SIZE)size_to_read = BLOCK_SIZE - offset;#使用IV和FEK解密數據res = tee_fs_htree_read_block(&fdp->ht, start_block_num, block);if (res != TEE_SUCCESS)goto exit;memcpy(data_ptr, block + offset, size_to_read);data_ptr += size_to_read;remain_bytes -= size_to_read;pos += size_to_read;start_block_num++;}res = TEE_SUCCESS;3.3 安全文件的寫入
寫數據和讀數據流程是類似的
@tee_fs_fs.c
@fs_htree.c
TEE_Result tee_fs_htree_write_block(struct tee_fs_htree **ht_arg,size_t block_num, const void *block) { ...res = get_block_node(ht, true, block_num, &node);res = ht->stor->rpc_write_init(ht->stor_aux, &op,TEE_FS_HTREE_TYPE_BLOCK, block_num,block_vers, &enc_block);res = authenc_init(&ctx, TEE_MODE_ENCRYPT, ht, &node->node,ht->stor->block_size);res = authenc_encrypt_final(ctx, node->node.tag, block,ht->stor->block_size, enc_block);res = ht->stor->rpc_write_final(&op); ... }=============================================================================================
4. 安全存儲中的加密解密
安全存儲中的安全文件和dirf.db文件中的數據內容都是按照一定的格式保存的,
主要由三部分組成:tee_fs_htree_image、tee_fs_htree_node_image和數據區域塊。
tee_fs_htree_image和tee_fs_htree_node_image結構體中保存的是安全文件操作時使用到的重要數據的密文數據;tee_fs_htree_image區域中的數據是對元數據經加密重要數據后生成的,而數據區域塊和tee_fs_htree_node_image中的數據則是對數據塊數據經加密后獲得的。
4.1 數據結構的組成與作用
tee_fs_htree_image主要保存加密頭部的IV值、加密安全文件的FEK使用的enc_fek以及加密之后生成的tag、imeta及標記兩個tee_fs_htree_image哪個為最新的counter值。
tee_fs_htree_node_image保存節點的哈希值、加密數據塊區域使用的IV值、標記使用哪個data block的ver的flag值以及加密需要被保存的數據時生成的tag數據。數據塊區域保存的是需要被保存的數據的密文數據。
tee_fs_htree_image中的imeta是按照元數據的方式經加密對應的數據獲得,tee_fs_htree_node_imaget中的tag跟數據塊中的數據則是按照數據塊加密策略經加密后獲得。
4.2 元數據的加密
tee_fs_htree_image區域中的數據是按照元數據方式經加密生成的,該加密過程如圖:
4.3 數據塊數據的加密
數據塊區域和tee_fs_htree_node_image中的數據是按照數據塊區域的加密策略經加密明文數據生成的,數據塊區域加密策略的加密過程如圖:
總結
安全存儲功能是OP-TEE中的一個重要功能,為用戶提供一個安全存取數據的方式。由于每次在對安全文件進行寫入操作時都會使用隨機數重新生成加密時使用的IV值,且加密時使用的密鑰也在創建安全文件時使用隨機數生成,并被加密保存到安全文件的頭部中,所以很難非法獲取到安全存儲中保存的明文數據。
內部實現的數據操作比較復雜,原理和RPMB的存儲有點類似,讀寫數據采用動態變化的參數如IV值或者Counter計數器值,防止重放或者暴力嘗試破解。
參考資料
《手機安全和可信應用開發指南》
總結
以上是生活随笔為你收集整理的OPTEE之安全存储详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python将excel转换成图片_py
- 下一篇: 用jsphtml:file实现一个文件上