基于 qemu 的 optee 模拟环境搭建

很早之前,参考CSDN博主“漂流的猴子”的两篇博客0.使用Qemu运行OP-TEEOP-TEE_3.6.0的qemu运行验证,尝试搭建过optee的模拟执行环境,但无论是在家里还是在公司里,都因为网络或其他莫名的原因而没有成功。

这次,误打误撞看到了optee官方文档中的搭建方法——Build and run,抱着尝试的心态,竟然搭建成功了!所以做个记录。

我用到的环境如下:

  • windows 10上安装的virtualbox 6.1.6版本。这个版本应该无所谓。

  • 虚拟机的系统是Ubuntu 18.04。

  • 安装的optee版本是3.8.0。

这里要提两个点,一开始我用的是Ubuntu 16.04版本安装optee 3.6.0,但是在安装依赖的时候一直报下面这个错,所以我就换成了Ubuntu 18.04。

1
E: Unable to locate package python3-pycryptodome

在Ubuntu 18.04上repo init的时候又报了一个错(具体是啥忘记了),原因是repo版本和optee版本不兼容。要么降低repo的版本(从2.x到1.x),要么使用新版本的optee。我选择了后者,使用Ubuntu 18.04,repo 2.x版本安装optee的3.8.0版本,最终环境搭建成功。

1 安装依赖

(1)因为安装的是64位的ubuntu,所以先使能系统对i386的支持。

1
2
$ sudo dpkg --add-architecture i386
$ sudo apt-get update

(2)安装所有需要用到的packages。

1
2
3
4
5
6
7
8
$ sudo apt-get install android-tools-adb android-tools-fastboot autoconf \
automake bc bison build-essential ccache cscope curl device-tree-compiler \
expect flex ftp-upload gdisk iasl libattr1-dev libcap-dev \
libfdt-dev libftdi-dev libglib2.0-dev libhidapi-dev libncurses5-dev \
libpixman-1-dev libssl-dev libtool make \
mtools netcat python-crypto python3-crypto python-pyelftools \
python3-pycryptodome python3-pyelftools python-serial python3-serial \
rsync unzip uuid-dev xdg-utils xterm xz-utils zlib1g-dev

2 安装android repo

如果系统之前没有android的开发环境,没有安装过repo的话,可以将repo下载到本地,然后添加到环境变量中。

1
2
3
4
5
6
$ mkdir ~/bin
$ vim ~/.bashrc
export PATH=~/bin:$PATH
$ source ~/.bashrc
$ curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
$ chmod a+x ~/bin/repo

3 获取源码

通过github上op-tee项目中的manifest指定版本来获取所需的源码,这种方法对于新手来说快捷省事。(repo之前需要设置好git的代理,保证能通过git访问外网)

1
2
3
4
$ mkdir -p optee
$ cd optee
$ repo init -u https://github.com/OP-TEE/manifest.git -m qemu_v8.xml -b 3.8.0
$ repo sync -j4 --no-clone-bundle

以上命令执行完如果没有任何问题的话,就可以直接跳到第4步去下载toolchain了。

但是很不幸,我在sync的时候遇到了这个错误——“GnuTLS recv error (-110): The TLS connection was non-properly terminated”,最后成功的解决办法是重装git,步骤如下。

1
2
3
4
5
6
7
8
9
10
11
12
$ sudo apt-get install build-essential fakeroot dpkg-dev -y
$ sudo apt-get build-dep git -y
$ sudo apt-get install libcurl4-openssl-dev -y
$ cd ~
$ mkdir source-git
$ cd source-git/
$ apt-get source git
$ cd git-2.*.*/
$ sed -i -- 's/libcurl4-gnutls-dev/libcurl4-openssl-dev/' ./debian/control
$ sed -i -- '/TEST\s*=\s*test/d' ./debian/rules
$ dpkg-buildpackage -rfakeroot -b -uc -us
$ sudo dpkg -i ../git_*ubuntu*.deb

4 下载toolchains

编译不同架构的op-tee时,需要用到不同的toolchain,因此我们需要事先下载好。

1
2
$ cd ~/optee/build
$ make -j2 toolchains

如果以上命令执行没有问题的话,继续去第5步就好啦。

我这里遇到一个问题:

  • make报错,提示在指定的目录中没有tar包。

    我仔细研究了一下,发现是没有下载下来。于是打开build目录下的toolchain.mk看了看这个脚本的实现。脚本第25行是curl -s -L $(2) -o $(TOOLCHAIN_ROOT)/$(3).tar.xz;,目的是下载一个tar包。去掉-s看看下载时到底发生了什么。果不其然,有错误提示curl: (60) SSL certificate problem: unable to get local issuer certificate。这是证书的问题,有两种方案:一种是在本地安装证书,另一种是curl下载时加上-k参数跳过证书检查。我选择第二种,因此将toolchain.mk中的第25行改成curl -k -L $(2) -o $(TOOLCHAIN_ROOT)/$(3).tar.xz;,然后就可以成功下载toolchain啦。

5 编译整个工程

因为在一开始已经设置过repo manifests了,所以编译的时候可以不指定版本,直接运行make。

1
2
3
4
$ cd ~/optee/build
$ make -j4
# 或者,将编译输出重定向到log中,方便编译出问题了定位
$ make 2>&1 | tee build.log

6 运行optee

在build目录下执行make run

1
2
$ cd ~/optee/build
$ make run

执行完后,一共会有三个窗口:qemu,非安全世界,安全世界。前两个窗口有shell,安全世界的窗口只有日志输出。

在qemu窗口中执行c,然后就可以在非安全世界的shell中执行xtest进行测试。

1
2
QEMU console:         (qemu) c
Normal world shell: # xtest

到此,整个基于qemu的optee环境就算搭建完成了,后续可以自由地进行分析和验证。

7 optee代码目录结构

一开始不明白为什么manifest下的default.xml和qemu_v8.xml两者代码目录不一样,最明显的,前者有uboot而后者没有,那后者是用什么引导启动的呢?

其实,default.xml编译的是32位的optee,而qemu_v8.xml编译的是64位的。64位的optee使用UEFI-EDK2替换掉了uboot,并引入加密组件mbedtls。这里参考了OPEN-TEE代码目录结构及编译目标这篇文章才弄懂的。

以qemu_v8.xml中的代码目录为例,如下是编译完成后的状态,out和out-br是编译过程中创建的目录。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
build/ - 不同平台的makefile及kconfig
buildroot/ - 一款编译工具
edk2/ - 遵循UEFI标准的bootloader源码
linux/ - linux kernel源码
mbedtls/ - 开源的ssl/tls加密组件,轻量级
optee_benchmark/ - open-tee项目基准框架的源码
optee_client/ - open-tee项目的非安全侧源码
optee_examples/ - open-tee中使用的示例CA和TA源码
optee_os/ - open-tee项目的os源码
optee_test/ - 测试套件xtest源码
out/ - 存储编译生成用于烧录的image,如bl1.bin, bl2.bin等
out-br/ - 存放buildroot工具编译生成的文件
qemu/ - qemu源码
.repo/ - repo工程
soc_term/ - 监听qemu、非安全终端、安全终端三个端口,正确将log重定向至对应的终端
toolchains/ - 包含编译所需的工具链
trusted-firmware-a/ - atf源码

8 后续研究

后面计划参考《手机安全和可信应用开发指南》及OP-TEE documentation对各个模块更深入地分析。

另一个任务是分析一些op-tee历年漏洞