OP-TEE内核学习笔记(一)(安全存储)—— 安全文件基础操作(创建、读、写)
目录
- 一、基本文件操作流程
- 1.1 安全文件的创建
- 1.2 安全文件的读取(待完善)
接上文:
OP-TEE内核学习笔记(一)(安全存储)—— GP 安全存储 API
OP-TEE内核学习笔记(一)(安全存储)—— 密钥和文件结构
了解了以上基本概述后,我们接下来看一下详细的安全文件的基础操作,了解OPTEE是如何处理安全文件的数据的。
因为OPTEE
中没有文件系统的功能,需要借助tee_supplicant
守护进程来完成访问文件系统的工作。读写安全文件也是类似的过程,TA
发送RPC
请求给tee_supplicant
,tee_supplicant
完成参数的解析和数据操作。
一、基本文件操作流程
当 TA 调用 GP 可信存储 API 提供的写入函数以将数据写入持久性对象时,将调用在 TEE 可信存储服务中实现的相应系统调用,而后者又会调用一系列 TEE 文件操作来存储数据。然后,TEE 文件系统将加密数据,并通过一系列 RPC 消息将 REE 文件操作命令和加密数据发送给 REE。REE将接收消息并相应地将加密数据存储到 Linux 文件系统。读取文件以类似的方式处理。架构图如图所示:
/** Returns the appropriate tee_file_operations * for the specified storage ID.* The value TEE_STORAGE_PRIVATE will select * the REE FS if available, otherwise RPMB.*/const struct tee_file_operations ree_fs_ops = {.open = ree_fs_open,.create = ree_fs_create,.close = ree_fs_close,.read = ree_fs_read,.write = ree_fs_write,.truncate = ree_fs_truncate,.rename = ree_fs_rename,.remove = ree_fs_remove,.opendir = ree_fs_opendir_rpc,.closedir = ree_fs_closedir_rpc,.readdir = ree_fs_readdir_rpc,
};const struct tee_file_operations rpmb_fs_ops = {.open = rpmb_fs_open,.create = rpmb_fs_create,.close = rpmb_fs_close,.read = rpmb_fs_read,.write = rpmb_fs_write,.truncate = rpmb_fs_truncate,.rename = rpmb_fs_rename,.remove = rpmb_fs_remove,.opendir = rpmb_fs_opendir,.closedir = rpmb_fs_closedir,.readdir = rpmb_fs_readdir,
};static const struct tee_file_operations *file_ops(uint32_t storage_id)
{switch (storage_id) {case TEE_STORAGE_PRIVATE:
#if defined(CFG_REE_FS)return &ree_fs_ops; /* TEE_STORAGE_PRIVATE * ree fs 服务可用,则直接使用ree fs文件系统 */
#elif defined(CFG_RPMB_FS)return &rpmb_fs_ops;
#else
#error At least one filesystem must be enabled.
#endif
#ifdef CFG_REE_FScase TEE_STORAGE_PRIVATE_REE:return &ree_fs_ops;
#endif
#ifdef CFG_RPMB_FScase TEE_STORAGE_PRIVATE_RPMB:return &rpmb_fs_ops;
#endifdefault:return NULL;}
}
以下安全文件的操作以REE_FS
为例进行分析。
1.1 安全文件的创建
在TA中调用TEE_CreatePersistentObject
接口时会创建安全文件。在创建安全文件时会初始化安全文件的数据区域。在OP-TEE
内核空间调用对应的读写接口syscall_storage_obj_create
函数来完成对安全文件中数据的创建。
TEE_CreatePersistentObject -> syscall_storage_obj_create -> tee_svc_storage_init_file -> ree_fs_open
我们看一下其中的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_open
函数get_dirh
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;
}static void put_dirh_primitive(bool close)
{assert(ree_fs_dirh_refcount);assert(ree_fs_dirh);ree_fs_dirh_refcount--; /* 引用次数为0,则将ree_fs_dirh置为空 */if (!ree_fs_dirh_refcount || close)close_dirh(&ree_fs_dirh);
}static void close_dirh(struct tee_fs_dirfile_dirh **dirh)
{tee_fs_dirfile_close(*dirh);*dirh = NULL;
}
通过ree_fs_dirh_refcount
全局变量 来控制是创建dirf.db
文件,还是打开dirf.db
文件。ree_fs_dirh_refcount
引用次数为0,则ree_fs_dirh为空,需要打开dirf.db
文件。
往下,我们继续看一下其中的ree_fs_open
函数ree_fs_open_primitive
函数:
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,
};
tee_ree_fs.c
中的 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)
{...if (create)res = tee_fs_rpc_create_dfh(OPTEE_MSG_RPC_CMD_FS,dfh, &fdp->fd);elseres = tee_fs_rpc_open_dfh(OPTEE_MSG_RPC_CMD_FS, dfh, &fdp->fd);if (res != TEE_SUCCESS)goto out;res = tee_fs_htree_open(create, hash, uuid, &ree_fs_storage_ops,fdp, &fdp->ht);
...
}
TEE_Result tee_fs_htree_open(bool create, uint8_t *hash, const TEE_UUID *uuid,const struct tee_fs_htree_storage *stor,void *stor_aux, struct tee_fs_htree **ht_ret)
{...if (create) {const struct tee_fs_htree_image dummy_head = { .counter = 0 };/* 在创建`dirf.db`文件过程中会产生一个随机数作为FEK,* 且在调用`update_root`函数时会产生另外一个随机数作为加密`FEK`的`IV`值* 并保存到`head.iv`中。每次文件的更新时,该IV值都会被新的随机数替代。 * */res = crypto_ops.prng.read(ht->fek, sizeof(ht->fek));if (res != TEE_SUCCESS)goto out;res = tee_fs_fek_crypt(ht->uuid, TEE_MODE_ENCRYPT, ht->fek,sizeof(ht->fek), ht->head.enc_fek);if (res != TEE_SUCCESS)goto out;/* 初始化root node, 计算ht->root.node.hash 后续校验时使用 */res = init_root_node(ht);/* 哈希树上内容通过后序遍历方式同步到安全存储文件上 */res = tee_fs_htree_sync_to_storage(&ht, hash);res = rpc_write_head(ht, 0, &dummy_head);} else {/* 读取dirf.db文件,调用rpc_read_node rpc_read* 读取dirf.db中的root node信息* 其中函数调用过程:init_head_from_data -> * rpc_read_node -> rpc_read */res = init_head_from_data(ht, hash);if (res != TEE_SUCCESS)goto out;/* 解密出root node内容并校验 */res = verify_root(ht);if (res != TEE_SUCCESS)goto out;/* 读取dirf.db中所有node信息并创建文件的节点树 */res = init_tree_from_data(ht);if (res != TEE_SUCCESS)goto out;/* #计算各节点内容的hash值,并与保存的hash进行比对,来校验整个hashtree是否合法 */res = verify_tree(ht);
...
}
安全文件创建完成之后,会将初始化数据加密后写入到安全文件中,然后更新整个安全文件的tee_fs_htree_node_image
区域以及保存在文件头的tee_fs_htree_image
区域,到此安全文件创建就已完毕。
为后续能够通过dirf.db
文件找到该安全文件,则还需要更新dirf. db
文件的内容,主要是更新dirf.db
文件数据区域中的dirfile_entry
数据。
1.2 安全文件的读取(待完善)
TA
对安全文件进行读写操作是通过调用TEE_ReadObjectData
和TEE_WriteObjectData
函数来实现的。这两个函数的执行最终会进入OP-TEE
的内核空间中。
在OP-TEE
内核空间调用对应的读写接口syscall_storage_obj_read
和syscall_storage_obj_write
函数来完成对安全文件中数据的读写操作。
OP-TEE内核学习笔记(一)(安全存储)—— 安全文件基础操作(创建、读、写)相关推荐
- 学习笔记Hadoop(十一)—— Hadoop基础操作(3)—— MapReduce常用Shell操作、MapReduce任务管理
四.MapReduce常用Shell操作 4.1.MapReduce常用Shell MapReduce Shell 此处指的是可以使用类似shell的命令来直接和MapReduce任务进行交互(这里不 ...
- 学习笔记Hadoop(十)—— Hadoop基础操作(2)—— HDFS常用Shell操作
三.HDFS常用Shell操作 3.1.HDFS文件系统 HDFS Shell 指的是可以使用类似shell的命令来直接和Hadoop分布式文件系统(HDFS)进行交互. 使用命令: bin/hado ...
- 学习笔记Hadoop(九)—— Hadoop基础操作(1)—— Hadoop安全模式、Hadoop集群基本信息
一.Hadoop安全模式 在分布式文件HDFS系统启动的时候,会有安全模式,当分布式文件系统处于安全模式的情况下,文件系统中的内容不允许修改也不允许删除,直到安全模式结束. 安全模式主要是为了系统启动 ...
- python学习笔记9.2-文件及文件夹操作
本文主要介绍python对文件以及文件夹的操作,主要涉及到文件的创建.读取.文件内容的修改.删除,文件夹的索引.目录的判断等等.此节内容非常重要,是以后编程的基础.python文件夹和文件的操作主要借 ...
- OP-TEE内核学习笔记(一)(安全存储)—— 安全存储 GP API
存储文件基础操作 一. 安全存储GP API 1.1 `TEE_CreatePersistentObject` 1.2 `TEE_CloseAndDeletePersistentObject` 1.3 ...
- 操作系统进程学习(Linux 内核学习笔记)
操作系统进程学习(Linux 内核学习笔记) 进程优先级 并非所有进程都具有相同的重要性.除了大多数我们所熟悉的进程优先级之外,进程还有不同的关键度类别,以满足不同需求.首先进程比较粗糙的划分,进程可 ...
- Windows x64内核学习笔记(五)—— KPTI(未完待续)
Windows x64内核学习笔记(五)-- KPTI(未完待续) KPTI 实验一:构造IDT后门并读取Cr3 参考资料 KPTI 描述:KPTI(Kernel page-table isolati ...
- Windows x64内核学习笔记(四)—— 9-9-9-9-12分页
Windows x64内核学习笔记(四)-- 9-9-9-9-12分页 前言 9-9-9-9-12分页 实验一:线性地址转物理地址 页表基址 定位基址 PTE to PXE 实验二:通过页表基址定位各 ...
- Windows x64内核学习笔记(三)—— SMEP SMAP
Windows x64内核学习笔记(三)-- SMEP & SMAP SMEP & SMAP 实验:构造IDT后门 第一步:编译以下代码 第二步:构造IDT后门 第三步:运行程序 第四 ...
- Windows x64内核学习笔记(一)—— 环境与配置
Windows x64内核学习笔记(一)-- 环境与配置 前言 新特性 基础要求 实验环境 Guest Win10配置 问题解决 参考资料 前言 之前,跟着海哥学习了windows内核的一些机制,包括 ...
最新文章
- 从数仓到数据中台,谈技术选型最优解
- Java自学路线总结,已Get腾讯Offer
- AI安防火热战况下 算法到场景还有多远?
- linux tomcat 进程杀掉_Linux下Tomcat的启动、关闭、杀死进程
- 成功解决CatBoostError: Invalid type for cat_feature cat_features must be integer or string, real number
- RabbitMq+Haproxy负载均衡
- Laravel项目迁移步骤
- Linux之vi三种模式常用操作的学习
- sql视图能使用触发器吗_冰箱买回家能立即使用吗 冰箱买回家要放多久能使用【详解】...
- 克罗谈投资策略04_感觉与现实
- 推荐12个非常不错而且免费的后台管理HTML模板
- 计算机网络实训室建设设备,计算机网络技术综合实训室建设方案.doc
- pycharm配置python第三方库_解决pycharm每次新建项目都要重新安装一些第三方库的问题...
- 【TWVRP】基于matlab遗传算法求解带时间窗+带充电桩的无人机巡检路径规划问题【含Matlab源码 YC001期】
- windows服务启动tomcat内存溢出问题解决方案
- 学术论文海报模板_推荐 | 绘制学术论文中的图表一般有哪些专业的软件?
- 键盘没有 菜单键 menu 键盘映射
- 【云栖大会精华汇】2017杭州云栖大会主论坛、分论坛在内的100+视频分享
- Angular入门-Hero Editor抽丝
- 4天4夜渡劫成功,解决10月1项目上线遇到的一个Mysql大坑,导致项目无法正常访问