第十四板块:Android 硬件抽象与安全加固 | 第三十三篇:Verified Boot 与 硬件信任链(Trusty TEE)
所属板块:第十四板块 --- Android 硬件抽象与安全加固
前置知识:第十三板块中的内存管理(LMK)、Linux 内核启动流程、SELinux 强制访问控制、加密文件系统(FBE)
本篇定位 :这是 Android 系统从硬件硅片到软件内核的绝对信任源头 。如果说 SELinux 是软件层面的警察,那么 Verified Boot(验证启动) 就是 验明正身的法官 。本篇将彻底拆解 Bootloader 的信任链传递 、Android Verified Boot (AVB) 2.0 的 vbmeta 结构与签名验证 、Trusty TEE (可信执行环境) 的 ARM TrustZone 实现 、安全世界(Secure World)与普通世界(Normal World)的 SMC 指令切换 。我们将深入 Bootloader 汇编代码 、TEE OS 内核,揭示 Android 如何确保在物理设备被窃取或 Root 后,核心机密(指纹、支付、DRM)依然固若金汤。全程无刷机教程、无 Root 指南,仅保留硬件安全架构的底层定义与密码学规范。
1. 核心结论先行(Thesis Statement)
Android 的硬件安全是一个基于密码学的单向信任传递过程。
- Verified Boot 的本质 :不可篡改的启动契约。它利用非对称加密(RSA/ECC),从 BootROM 开始,每一步都验证下一步代码的数字签名。任何对系统分区的物理篡改都会导致签名验证失败,进而阻止设备启动,或使安全功能(如 Widevine L1)降级。
- Trusty TEE 的本质 :与主系统隔离的微型安全内核。它运行在 ARM TrustZone 的"安全世界"中,拥有独立的 MMU 和内存空间。即使 Android 系统(普通世界)被黑客完全控制(Root),也无法读取或修改 TEE 中的指纹密钥或支付数据。
- 信任链(Chain of Trust)的本质 :从硅片到软件的接力棒。BootROM -> Bootloader -> vbmeta -> Kernel -> init。每一棒都必须验证下一棒的身份,一旦断链,全盘皆输。
- SMC 指令的本质 :穿越两个世界的虫洞 。普通世界通过
SMC (Secure Monitor Call)指令陷入特权模式,切换到安全世界执行敏感操作,完成后返回。
2. 硬件安全架构全景图
2.1 从 BootROM 到 TEE OS
#mermaid-svg-l9r8I9iU6iSUO1Zk{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-l9r8I9iU6iSUO1Zk .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-l9r8I9iU6iSUO1Zk .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-l9r8I9iU6iSUO1Zk .error-icon{fill:#552222;}#mermaid-svg-l9r8I9iU6iSUO1Zk .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-l9r8I9iU6iSUO1Zk .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-l9r8I9iU6iSUO1Zk .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-l9r8I9iU6iSUO1Zk .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-l9r8I9iU6iSUO1Zk .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-l9r8I9iU6iSUO1Zk .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-l9r8I9iU6iSUO1Zk .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-l9r8I9iU6iSUO1Zk .marker{fill:#333333;stroke:#333333;}#mermaid-svg-l9r8I9iU6iSUO1Zk .marker.cross{stroke:#333333;}#mermaid-svg-l9r8I9iU6iSUO1Zk svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-l9r8I9iU6iSUO1Zk p{margin:0;}#mermaid-svg-l9r8I9iU6iSUO1Zk .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-l9r8I9iU6iSUO1Zk .cluster-label text{fill:#333;}#mermaid-svg-l9r8I9iU6iSUO1Zk .cluster-label span{color:#333;}#mermaid-svg-l9r8I9iU6iSUO1Zk .cluster-label span p{background-color:transparent;}#mermaid-svg-l9r8I9iU6iSUO1Zk .label text,#mermaid-svg-l9r8I9iU6iSUO1Zk span{fill:#333;color:#333;}#mermaid-svg-l9r8I9iU6iSUO1Zk .node rect,#mermaid-svg-l9r8I9iU6iSUO1Zk .node circle,#mermaid-svg-l9r8I9iU6iSUO1Zk .node ellipse,#mermaid-svg-l9r8I9iU6iSUO1Zk .node polygon,#mermaid-svg-l9r8I9iU6iSUO1Zk .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-l9r8I9iU6iSUO1Zk .rough-node .label text,#mermaid-svg-l9r8I9iU6iSUO1Zk .node .label text,#mermaid-svg-l9r8I9iU6iSUO1Zk .image-shape .label,#mermaid-svg-l9r8I9iU6iSUO1Zk .icon-shape .label{text-anchor:middle;}#mermaid-svg-l9r8I9iU6iSUO1Zk .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-l9r8I9iU6iSUO1Zk .rough-node .label,#mermaid-svg-l9r8I9iU6iSUO1Zk .node .label,#mermaid-svg-l9r8I9iU6iSUO1Zk .image-shape .label,#mermaid-svg-l9r8I9iU6iSUO1Zk .icon-shape .label{text-align:center;}#mermaid-svg-l9r8I9iU6iSUO1Zk .node.clickable{cursor:pointer;}#mermaid-svg-l9r8I9iU6iSUO1Zk .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-l9r8I9iU6iSUO1Zk .arrowheadPath{fill:#333333;}#mermaid-svg-l9r8I9iU6iSUO1Zk .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-l9r8I9iU6iSUO1Zk .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-l9r8I9iU6iSUO1Zk .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-l9r8I9iU6iSUO1Zk .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-l9r8I9iU6iSUO1Zk .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-l9r8I9iU6iSUO1Zk .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-l9r8I9iU6iSUO1Zk .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-l9r8I9iU6iSUO1Zk .cluster text{fill:#333;}#mermaid-svg-l9r8I9iU6iSUO1Zk .cluster span{color:#333;}#mermaid-svg-l9r8I9iU6iSUO1Zk div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-l9r8I9iU6iSUO1Zk .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-l9r8I9iU6iSUO1Zk rect.text{fill:none;stroke-width:0;}#mermaid-svg-l9r8I9iU6iSUO1Zk .icon-shape,#mermaid-svg-l9r8I9iU6iSUO1Zk .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-l9r8I9iU6iSUO1Zk .icon-shape p,#mermaid-svg-l9r8I9iU6iSUO1Zk .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-l9r8I9iU6iSUO1Zk .icon-shape .label rect,#mermaid-svg-l9r8I9iU6iSUO1Zk .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-l9r8I9iU6iSUO1Zk .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-l9r8I9iU6iSUO1Zk .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-l9r8I9iU6iSUO1Zk :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 普通世界 (Android)
安全世界 (TrustZone)
硅片 (SoC)
- 验证 OTP
- 验证 BL1
- 初始化 TZ
- 验证 BL2
- 验证 Kernel
- 启动
SMC 指令
操作硬件
BootROM (固化在芯片)
OTP 熔丝 (公钥 Hash)
硬件加密引擎 (AES/RSA)
BL1 (EL3 Firmware)
Trusty TEE OS
KeyMaster
Gatekeeper (生物识别)
BL2 (Little Kernel)
Linux Kernel
Android System
2.2 核心组件职责表
| 组件 | 层级 | 职责 | 学术定义 |
|---|---|---|---|
| BootROM | Hardware | 信任根 | 芯片出厂时固化的代码,不可修改,负责加载并验证 Bootloader。 |
| OTP (One-Time Programmable) | Hardware | 密钥存储 | 熔丝烧录的公钥 Hash,用于验证 Bootloader 签名。 |
| TrustZone | ARM Arch | 硬件隔离 | CPU 的安全扩展,将硬件资源(内存、中断)划分为安全和普通两个世界。 |
| Trusty TEE | Software | 安全内核 | 运行在 TrustZone 中的微型 OS,提供安全服务(密钥管理、生物识别)。 |
| SMC (Secure Monitor Call) | Instruction | 世界切换 | 从普通世界切换到安全世界的 CPU 指令。 |
3. Verified Boot 与 AVB 2.0
3.1 信任链的传递
信任链是单向且不可逆的。
- BootROM (Root of Trust): 芯片上电,执行固化代码。它读取 OTP 中的公钥 Hash,验证 BL1 的签名。
- BL1 (EL3): 验证通过,加载 BL1。BL1 初始化 TrustZone,验证 BL2(Little Kernel)的签名。
- BL2 (Little Kernel): 验证通过,加载 Android Boot Image(Kernel + Ramdisk)的签名。
- Kernel: 验证通过,启动 Linux 内核。
3.2 Android Verified Boot (AVB) 2.0
AVB 2.0 引入了 vbmeta 分区。
学术定义:
- vbmeta 分区:一个特殊的分区,包含其他分区(boot, system, vendor)的哈希值和签名。
- 链式分区:vbmeta 可以信任其他 vbmeta(如 vendor 分区),实现分区独立性。
vbmeta 结构:
protobuf
// VBMeta 数据结构
message VBMeta {
required bytes header = 1; // 魔数、版本
repeated Descriptor descriptors = 2; // 描述符 (哈希、属性)
required bytes signature = 3; // 对 header+descriptors 的签名
}
// 描述符示例
message HashDescriptor {
required string partition_name = 1; // "boot"
required bytes hash_algorithm = 2; // "sha256"
required bytes salt = 3; // 盐值
required bytes digest = 4; // 分区内容的哈希值
}
验证流程:
- Bootloader 读取 vbmeta 分区。
- 使用 OTP 中的公钥验证 vbmeta 的签名。
- 如果通过,遍历 descriptors,计算每个分区(boot, system)的哈希值。
- 对比计算出的哈希值与 descriptor 中的哈希值。
- 完全一致,才允许启动。
4. Trusty TEE 与 ARM TrustZone
4.1 TrustZone 的内存隔离
TrustZone 通过硬件 MMU 实现隔离。
| 特性 | 普通世界 (Normal World) | 安全世界 (Secure World) |
|---|---|---|
| CPU 状态 | Non-secure (NS=1) | Secure (NS=0) |
| 内存访问 | 只能访问普通内存 | 可以访问安全和普通内存 |
| 中断 | IRQ | FIQ (快速中断) |
| MMU | 独立页表 | 独立页表 |
学术定义:
- TZASC (TrustZone Address Space Controller) : 硬件单元,控制哪些内存区域属于安全世界。普通世界访问安全内存会触发 SError(系统错误)。
- TZPC (TrustZone Protection Controller): 控制外设(如键盘、指纹传感器)属于哪个世界。
4.2 Trusty OS 架构
Trusty 是 Google 为 Android 开发的 TEE OS。
#mermaid-svg-e31u2kAmul3817iw{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-e31u2kAmul3817iw .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-e31u2kAmul3817iw .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-e31u2kAmul3817iw .error-icon{fill:#552222;}#mermaid-svg-e31u2kAmul3817iw .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-e31u2kAmul3817iw .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-e31u2kAmul3817iw .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-e31u2kAmul3817iw .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-e31u2kAmul3817iw .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-e31u2kAmul3817iw .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-e31u2kAmul3817iw .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-e31u2kAmul3817iw .marker{fill:#333333;stroke:#333333;}#mermaid-svg-e31u2kAmul3817iw .marker.cross{stroke:#333333;}#mermaid-svg-e31u2kAmul3817iw svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-e31u2kAmul3817iw p{margin:0;}#mermaid-svg-e31u2kAmul3817iw .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-e31u2kAmul3817iw .cluster-label text{fill:#333;}#mermaid-svg-e31u2kAmul3817iw .cluster-label span{color:#333;}#mermaid-svg-e31u2kAmul3817iw .cluster-label span p{background-color:transparent;}#mermaid-svg-e31u2kAmul3817iw .label text,#mermaid-svg-e31u2kAmul3817iw span{fill:#333;color:#333;}#mermaid-svg-e31u2kAmul3817iw .node rect,#mermaid-svg-e31u2kAmul3817iw .node circle,#mermaid-svg-e31u2kAmul3817iw .node ellipse,#mermaid-svg-e31u2kAmul3817iw .node polygon,#mermaid-svg-e31u2kAmul3817iw .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-e31u2kAmul3817iw .rough-node .label text,#mermaid-svg-e31u2kAmul3817iw .node .label text,#mermaid-svg-e31u2kAmul3817iw .image-shape .label,#mermaid-svg-e31u2kAmul3817iw .icon-shape .label{text-anchor:middle;}#mermaid-svg-e31u2kAmul3817iw .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-e31u2kAmul3817iw .rough-node .label,#mermaid-svg-e31u2kAmul3817iw .node .label,#mermaid-svg-e31u2kAmul3817iw .image-shape .label,#mermaid-svg-e31u2kAmul3817iw .icon-shape .label{text-align:center;}#mermaid-svg-e31u2kAmul3817iw .node.clickable{cursor:pointer;}#mermaid-svg-e31u2kAmul3817iw .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-e31u2kAmul3817iw .arrowheadPath{fill:#333333;}#mermaid-svg-e31u2kAmul3817iw .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-e31u2kAmul3817iw .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-e31u2kAmul3817iw .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-e31u2kAmul3817iw .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-e31u2kAmul3817iw .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-e31u2kAmul3817iw .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-e31u2kAmul3817iw .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-e31u2kAmul3817iw .cluster text{fill:#333;}#mermaid-svg-e31u2kAmul3817iw .cluster span{color:#333;}#mermaid-svg-e31u2kAmul3817iw div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-e31u2kAmul3817iw .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-e31u2kAmul3817iw rect.text{fill:none;stroke-width:0;}#mermaid-svg-e31u2kAmul3817iw .icon-shape,#mermaid-svg-e31u2kAmul3817iw .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-e31u2kAmul3817iw .icon-shape p,#mermaid-svg-e31u2kAmul3817iw .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-e31u2kAmul3817iw .icon-shape .label rect,#mermaid-svg-e31u2kAmul3817iw .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-e31u2kAmul3817iw .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-e31u2kAmul3817iw .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-e31u2kAmul3817iw :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 硬件
Secure Drivers
Trusty TEE OS
Trusty Kernel (LK)
Trusty Apps
Keymaster TA
Gatekeeper TA
加密驱动
SPI 驱动 (指纹)
I2C 驱动 (传感器)
加密引擎
指纹传感器
4.3 SMC 指令与世界切换
当 Android 需要生成 AES 密钥时:
- Android 应用 调用 Framework API (
generateKey()). - Framework 通过 Binder 调用 Keystore Service.
- Keystore Service 发现需要硬件支持,调用 libtrusty.
- libtrusty 执行
SMC指令,CPU 切换到 EL3 (Secure Monitor). - Secure Monitor 保存普通世界上下文,切换到 安全世界 页表,跳转到 Trusty Kernel.
- Trusty Kernel 执行 Keymaster TA,生成密钥,存储在安全内存中。
- 操作完成,SMC 切回普通世界,返回结果。
5. 关键安全服务:KeyMaster 与 Gatekeeper
5.1 KeyMaster (密钥管理)
KeyMaster 运行在 TEE 中,负责生成和存储加密密钥。
学术定义:
- Keymaster HAL: Android 与 TEE 的接口。
- Hardware-backed Key: 密钥材料永远不会离开 TEE。Android 系统只拿到一个"句柄"。
- Key Attestation (密钥认证): 密钥生成时,TEE 会用私钥对密钥属性进行签名。云端可以验证这个签名,确认密钥确实来自硬件安全环境。
5.2 Gatekeeper (门卫)
Gatekeeper 负责验证用户身份(PIN/Pattern/Password)。
学术定义:
- Enroll (注册) : 用户输入密码,Gatekeeper 使用 Scrypt 算法生成密码哈希,存储在 TEE 中。
- Verify (验证): 用户输入密码,Gatekeeper 计算哈希并与存储值比对。
- 防暴力破解: TEE 内部实现延时和尝试次数限制,即使 Root 也无法绕过。
6. 关键源码深度解析
6.1 AVB 验证代码(Bootloader)
c
// Bootloader 中的 AVB 验证
AvbOps ops = {
.read_is_device_unlocked = read_is_device_unlocked,
.read_from_partition = read_from_partition,
.validate_vbmeta_public_key = validate_vbmeta_public_key,
};
// 验证 vbmeta
if (avb_slot_verify(ops, requested_partitions, ...) != AVB_SLOT_VERIFY_RESULT_OK) {
// 验证失败,进入 fastboot 或警告
die("AVB verification failed!");
}
6.2 Trusty SMC 调用
c
// Android 侧调用 TEE
long trusty_std_call(uint32_t smcnr, void *args, size_t args_len) {
struct trusty_msg msg;
msg.smc_nr = smcnr;
msg.args = args;
msg.args_len = args_len;
// 触发 SMC 指令
asm volatile (
"smc #0\n"
: "=r" (ret)
: "r" (msg)
);
return ret;
}
7. 硬件安全的常见误区
| 误区 | 学术解释 |
|---|---|
| Root 就能拿到所有数据 | 错误。Root 只能控制普通世界。TEE 中的数据(指纹、支付密钥)Root 拿不到。 |
| 刷机就能绕过验证 | 部分正确。如果 Bootloader 未解锁,无法刷入未签名镜像。解锁 Bootloader 会擦除数据并触发 dm-verity 错误。 |
| TEE 绝对安全 | 相对。TEE 也有漏洞(如侧信道攻击),但攻击难度极高。 |
| DRM L1 只靠软件 | 错误。Widevine L1 要求硬件支持(TEE 和加密引擎),软件破解无法升级到 L1。 |
8. 本篇总结(Knowledge Closure)
| 关键点 | 纯学术定义 |
|---|---|
| Verified Boot | 基于非对称加密的单向信任链,确保系统代码完整性。 |
| Trusty TEE | 运行在 ARM TrustZone 中的安全内核,提供隔离的可信执行环境。 |
| SMC 指令 | 连接普通世界与安全世界的硬件桥梁,实现特权切换。 |
| KeyMaster | 硬件支持的密钥管理,密钥材料永不离开 TEE。 |
| 攻击面收敛 | 将攻击面从整个 Android 系统收敛到微小的 TEE 内核。 |
9. 第十四板块结语
至此,第十四板块:Android 硬件抽象与安全加固 的第一篇已完成。
我们从 BootROM 的信任根 出发,深入 AVB 2.0 的签名验证 ,探索 TrustZone 的硬件隔离 ,最终抵达 TEE 中的密钥管理。
我们揭示了 Android 硬件安全的核心逻辑:用硅片固化信任,用密码学验证代码,用硬件隔离保护数据。
下一篇预告 :第十四板块:Android 硬件抽象与安全加固 | 第三十四篇:Hardware Composer (HWC) 与 显示安全(HDCP)