写在之前
这两篇文章是我2021年3月初看KeyMaster的笔记,本来打算等分析完KeyMaster和KeyStore以后再一起做成一系列贴出来,后来KeyStore的分析中断了,这一系列的文章就变得遥遥无期。今天群里聊天时有个朋友问到文章的事,我觉得可能多少还有些价值,做了一些脱敏后发出来,希望对你阅读KeyMaster代码有些帮助,尤其阅读代码的方法,如何从0开始查找,分析代码。
相关文章:
Android Q 10.1 KeyMaster源码分析(一) - KeyMaster相关目录和文件
Android Q 10.1 KeyMaster源码分析(二) - 各家方案的实现
本文分两部分,第一部分演示我是如何查找并分析代码的,如果觉得第二部分太啰嗦,请直接跳转到第二部分,关于代码的解析。
代码版本
$ grep -rn QTG1 build/ 2>/dev/null build/make/core/build_id.mk:21:BUILD_ID=QTG1.201104.001
第一部分,我是如何从零开始查找代码的
为什么要第一步先确定模块包含哪些目录和文件呢?
主要是Android是一个庞大的系统,需要明白keymaster在这个系统中的地位和作用。
尝试查找代码相关的目录:
1. 使用find和grep等工具
查找主要有三部分:
- 查找keymaster模块相关的目录,这些目录下的内容基本上都是专门针对keymaster的实现或介绍的
- 查找keymaster模块相关的文件,除了这些叫做keymaster的目录外,还有些模块会包装keymaster模块的内容,这些文件名字中可能会包含keymaster
- 查找包含keymaster相关函数调用的文件,比如什么时候进行keymaster初始化,什么时候调用keymaster进行操作等
查找代码中所有文件夹和文件名中包含keymaster字符串的文件夹和文件。
在Android Q代码(QTG1.201104.001)下查找跟keymaster相关的目录
# rocky@guyongqiangx:/public/ygu/android-q-ab2/src-km$
src-km$ find . -path ./out -prune -o -path ./.repo -prune \
-o -type d -iname "*keymaster*" -print -prune
./vendor/broadcom/refsw/BSEAV/lib/security/sage/keymaster
./vendor/broadcom/refsw/BSEAV/lib/security/astra/keymaster
./vendor/broadcom/bcm_platform/hals/keymaster
./hardware/interfaces/keymaster
./hardware/libhardware/tests/keymaster
./hardware/qcom/keymaster
./test/vts-testcase/hal/keymaster
./test/vts-testcase/fuzz/config/keymaster
./test/vts-testcase/hal-trace/keymaster
./device/generic/goldfish/keymaster
./external/autotest/server/site_tests/brillo_Keymaster
./system/keymaster
./system/core/trusty/keymaster
./system/security/keystore/binder/android/security/keymaster
./frameworks/base/core/java/android/security/keymaster
在除去上面的路径中,剩下的名字包含"keymaster"的文件有:
$ find . -path ./out -prune -o -path ./prebuilts -prune -o -path ./test -prune -o -path ./.repo -prune \
-o -type d -iname "*keymaster*" -prune \
-o -type f -iname "*keymaster*" -print
./vendor/broadcom/bcm_platform/docs/Android_KeyMaster-GateKeeper.pdf
./vendor/broadcom/bcm_platform/prop/keymaster_props.h
./hardware/libhardware/include/hardware/keymaster0.h
./hardware/libhardware/include/hardware/keymaster_defs.h
./hardware/libhardware/include/hardware/keymaster2.h
./hardware/libhardware/include/hardware/keymaster1.h
./hardware/libhardware/include/hardware/keymaster_common.h
./device/broadcom/common/sepolicy/common/hal_keymaster_default.te
./device/broadcom/common/sepolicy/nx_20/hal_keymaster_default.te
./device/broadcom/common/sepolicy/nx_19/hal_keymaster_default.te
./system/vold/Keymaster.cpp
./system/vold/Keymaster.h
./system/vold/wait_for_keymaster.cpp
./system/vold/wait_for_keymaster.rc
./system/security/keystore/keystore_keymaster_enforcement.h
./system/security/keystore/include/keystore/keymaster_types.h
./system/security/keystore/include/keystore/KeymasterCertificateChain.h
./system/security/keystore/include/keystore/KeymasterBlob.h
./system/security/keystore/include/keystore/KeymasterArguments.h
./system/security/keystore/keymaster_worker.h
./system/security/keystore/legacy_keymaster_device_wrapper.cpp
./system/security/keystore/legacy_keymaster_device_wrapper.h
./system/security/keystore/keymaster_enforcement.cpp
./system/security/keystore/keymaster_enforcement.h
./system/security/keystore/KeymasterArguments.cpp
./system/security/keystore/keymaster_worker.cpp
./system/sepolicy/vendor/hal_keymaster_default.te
./system/sepolicy/public/hal_keymaster.te
./system/sepolicy/private/wait_for_keymaster.te
./system/sepolicy/prebuilts/api/29.0/public/hal_keymaster.te
./system/sepolicy/prebuilts/api/29.0/private/wait_for_keymaster.te
./system/sepolicy/prebuilts/api/28.0/public/hal_keymaster.te
./system/sepolicy/prebuilts/api/28.0/private/wait_for_keymaster.te
./system/sepolicy/prebuilts/api/26.0/public/hal_keymaster.te
./system/sepolicy/prebuilts/api/27.0/public/hal_keymaster.te
./frameworks/base/keystore/java/android/security/keystore/KeymasterUtils.java
这里的筛选条件:
$ find . -path ./out -prune -o -path ./prebuilts -prune -o -path ./test -prune -o -path ./.repo -prune -o -ipath "*keymaster/*" -prune -o -type f \( ! -iname "*.txt" -a ! -iname "*.bin" -a -iname "*keymaster*" \) -print
1. 目录名不包含 ./{out,prebuilts,test,.repo}
"-path ./out -prune -o -path ./prebuilts -prune -o -path ./test -prune -o -path ./.repo -prune"
2. 目录名不包含keymaster
"-ipath "*keymaster/*" -prune"
3. 文件名包含keymaster, 但不是*.txt和*.bin文件
"-type f \( ! -iname "*.txt" -a ! -iname "*.bin" -a -iname "*keymaster*" \)"
也可以直接一个命令查找名字中包含"keymaster"字符串的目录和文件:
$ find . -path ./out -prune -o -path ./.repo -prune -o -path ./prebuilts -prune -o -path ./test -prune -o -type d -iname "*keymaster*" -print -prune -o -type f -iname "*keymaster*" -print $ find . -path ./out -prune -o -path ./.repo -prune -o -path ./prebuilts -prune -o -path ./test -prune \ -o -type d -iname "*keymaster*" -print -prune \ -o -type f -iname "*keymaster*" -print
筛选条件:
-path ./out -prune -o -path ./.repo -prune -o -path ./prebuilts -prune -o -path ./test -prune
,排除./out, ./.repo, ./prebuilts, ./test
目录;-type d -iname "*keymaster*" -print -prune
,搜索并打印名字包含"keymaster"的目录,找到以后不再继续往下搜索;-type f -iname "*keymaster*" -print
,搜索并答应名字包含"keymaster"的文件;
2. 使用交叉引用工具
第二部分,KeyMaster相关的目录和文件汇总
在我手上的Broadcom机顶盒使用的Android Q代码中, 跟keymaster相关的目录有:
# keymaster的接口定义
./hardware/interfaces/keymaster
# keymaster的接口测试
./hardware/libhardware/tests/keymaster
# keymaster系统实现(Vendor之上)
./system/keymaster
# 基于Android Trusty TEE的keymaster实现
./system/core/trusty/keymaster
# 用于给keystore调用的keymaster接口定义
./system/security/keystore/binder/android/security/keymaster
# framework层的keymaster接口实现
./frameworks/base/core/java/android/security/keymaster
# Broadcom的keymaster底层私有实现
./vendor/broadcom/refsw/BSEAV/lib/security/sage/keymaster
./vendor/broadcom/refsw/BSEAV/lib/security/astra/keymaster
./vendor/broadcom/bcm_platform/hals/keymaster
# Qualcomm的keymaster底层私有实现
./hardware/qcom/keymaster
# ARM仿真环境goldfish的keymaster底层实现
./device/generic/goldfish/keymaster
# keymaster相关的vts测试
./test/vts-testcase/hal/keymaster
./test/vts-testcase/fuzz/config/keymaster
./test/vts-testcase/hal-trace/keymaster
# brillo相关的keymaster测试
./external/autotest/server/site_tests/brillo_Keymaster
除去上面跟keymaster相关的目录,剩余的相关文件有:
# Broadcom的keymaster文档和私有定义
./vendor/broadcom/bcm_platform/docs/Android_KeyMaster-GateKeeper.pdf
./vendor/broadcom/bcm_platform/prop/keymaster_props.h
# keymaster早期版本的头文件定义
./hardware/libhardware/include/hardware/keymaster0.h
./hardware/libhardware/include/hardware/keymaster_defs.h
./hardware/libhardware/include/hardware/keymaster2.h
./hardware/libhardware/include/hardware/keymaster1.h
./hardware/libhardware/include/hardware/keymaster_common.h
# Broadcom的keymaster sepolicy文件
./device/broadcom/common/sepolicy/common/hal_keymaster_default.te
./device/broadcom/common/sepolicy/nx_20/hal_keymaster_default.te
./device/broadcom/common/sepolicy/nx_19/hal_keymaster_default.te
# Vold对keymaster的调用
./system/vold/Keymaster.cpp
./system/vold/Keymaster.h
./system/vold/wait_for_keymaster.cpp
./system/vold/wait_for_keymaster.rc
# keystore对keymaster的包装和调用
./system/security/keystore/keystore_keymaster_enforcement.h
./system/security/keystore/include/keystore/keymaster_types.h
./system/security/keystore/include/keystore/KeymasterCertificateChain.h
./system/security/keystore/include/keystore/KeymasterBlob.h
./system/security/keystore/include/keystore/KeymasterArguments.h
./system/security/keystore/keymaster_worker.h
./system/security/keystore/legacy_keymaster_device_wrapper.cpp
./system/security/keystore/legacy_keymaster_device_wrapper.h
./system/security/keystore/keymaster_enforcement.cpp
./system/security/keystore/keymaster_enforcement.h
./system/security/keystore/KeymasterArguments.cpp
./system/security/keystore/keymaster_worker.cpp
# 各种keymaster相关的sepolicy文件
./system/sepolicy/vendor/hal_keymaster_default.te
./system/sepolicy/public/hal_keymaster.te
./system/sepolicy/private/wait_for_keymaster.te
./system/sepolicy/prebuilts/api/29.0/public/hal_keymaster.te
./system/sepolicy/prebuilts/api/29.0/private/wait_for_keymaster.te
./system/sepolicy/prebuilts/api/28.0/public/hal_keymaster.te
./system/sepolicy/prebuilts/api/28.0/private/wait_for_keymaster.te
./system/sepolicy/prebuilts/api/26.0/public/hal_keymaster.te
./system/sepolicy/prebuilts/api/27.0/public/hal_keymaster.te
# framework下keystore模块中的keymaster工具包
./frameworks/base/keystore/java/android/security/keystore/KeymasterUtils.java
说重点:
- keymaster的接口定于位于
./hardware/interfaces/keymaster
- 接口定义文件包含了非常详细的注释
hardware/interfaces/keymaster/3.0/IKeymasterDevice.hal
hardware/interfaces/keymaster/4.0/IKeymasterDevice.hal
- 接口定义文件包含了非常详细的注释
- keymaster的系统实现位于
./system/keymaster
- keymaster的Vendor实现有3个,分别是:
- Broadcom实现,位于
./vendor/broadcom
- 相关文档:
./vendor/broadcom/bcm_platform/docs/Android_KeyMaster-GateKeeper.pdf
- 相关文档:
- Qualcomm实现,位于
./hardware/qcom/keymaster
- 仿真的goldfish,位于
./device/generic/goldfish/keymaster
- Broadcom实现,位于
- keystore模块有大量对keymaster的包装和引用,位于
./system/security/keystore
- Vold模块对keymaster的包装和引用,位于
./system/vold
接下来的代码分析包括以下几个部分:
- keymaster核心代码
- keymaster的各个底层实现
- Qualcomm实现
- 底层基于QSEECom
- 仿真goldfish实现
- 底层基于Trusty keymaster
- Qualcomm实现
- keymaster的上层调用分析,包括
- keystore模块对keymaster的调用
- vold模块对keymaster的调用
广告
洛奇工作中常常会遇到自己不熟悉的问题,这些问题可能并不难,但因为不了解,找不到人帮忙而瞎折腾,往往导致浪费几天甚至更久的时间。
所以我组建了几个微信讨论群(记得微信我说加哪个群,如何加微信见后面),欢迎一起讨论:
- 一个密码编码学讨论组,主要讨论各种加解密,签名校验等算法,请说明加密码学讨论群。
- 一个Android OTA的讨论组,请说明加Android OTA群。
- 一个git和repo的讨论组,请说明加git和repo群。
在工作之余,洛奇尽量写一些对大家有用的东西,如果洛奇的这篇文章让您有所收获,解决了您一直以来未能解决的问题,不妨赞赏一下洛奇,这也是对洛奇付出的最大鼓励。扫下面的二维码赞赏洛奇,金额随意:
洛奇自己维护了一个公众号“洛奇看世界”,一个很佛系的公众号,不定期瞎逼逼。公号也提供个人联系方式,一些资源,说不定会有意外的收获,详细内容见公号提示。扫下方二维码关注公众号: