secure boot (二)基本概念和框架
什么是secure boot
secure boot是指确保在一个平台上运行的程序的完整性的过程或机制。secure boot会在固件和应用程序之间建立一种信任关系。在启用secure boot功能后,未经签名的固件或程序将不能运行在该设备上。
通过这种方式,可以保护操作系统免受恶意攻击。secure boot一般使用公钥/私钥来验证固件和应用程序的签名是否合法。
为什么需要secure boot
嵌入式设备启动一般从bootrom开始,逐级加载spl,uboot,linux,应用程序。
该流程中由bootrom开始,逐级通过spl、uboot以启动linux操作系统。
我们假设spl、uboot和linux镜像都被保存在flash上,则在启动时,各级启动程序都需要从flash中加载下一级启动镜像,其流程示意图如下:
如果以上流程未执行secure boot,则flash中的镜像一旦被恶意攻击者替换掉,那么最终系统上将会运行被攻击者篡改过的固件。
假设linux和rootfs被替换掉以后,那么启动后整个系统都将掌握在攻击者的手里。从而导致在操作系统之上构建的所有安全机制都形同虚设。
secure boot预备知识
安全级别
ARMv8分为Secure World和Non-Secure World(Normal World),四种异常级别从高到低分别为EL3,EL2,EL1,EL0。
EL3具有最高管理权限,负责安全监测和Secure World和Normal World之间的切换。
EL2主要提供了对虚拟化的支持。
EL1是一个特权模式,能够执行一些特权指令,用于运行各类操作系统,在Secure World则是secure OS(如TEE)。
EL0是无特权模式,所有APP应用都在EL0。
启动流程
上图中的BL1,BL2,BL31,BL32,BL33分别对应如下功能:
BL1
BL1是信任链的根所在,一般是固化在芯片内部的一段代码,叫做bootrom,具有最高的执行权限EL3,在 CPU 出厂时就被写死了。
bootrom通常会被映射到它专属的一块内存地址中,但是如果你尝试向这块地址写入内容,一般都会出错。
芯片上电或复位后,bootrom的代码会从固定位置加载BL2来初始化sram,在BL2 验签通过后会跳转到BL2 ,以保证可信任执行。
BL2
BL2和BL1一样,也是运行在EL3特权级别的,不同的是BL2在flash中的一段可信安全启动代码,它的可信建立在BL1对它的验证,主要完成一些平台相关的初始化,比如对ddr的初始化等。
在完成初始化后寻找BL31或者BL33进行执行;如果找到了BL31则不会继续调用BL33,如果没有BL31则BL33必须有。
BL31
BL31作为EL3最后的安全堡垒,它不像BL1和BL2是一次性运行的。如它的runtime名字暗示的那样,它通过SMC指令为Non-Secure持续提供设计安全的服务,在Secure World和Non-Secure World之间进行切换。它的主要任务是找到BL32,验签,并运行BL32。
BL32
BL32是所谓的secure os,在ARM平台下是 ARM 家的 Trusted Execution Environment(TEE)实现。OP-TEE 是基于ARM TrustZone硬件架构所实现的软件Secure OS。
一般在BL32会运行OPTee OS + 安全app,它是一个可信安全的OS运行在EL1并在EL0启动可信任APP(如指纹信息,移动支付的密码等),并在Trust OS运行完成后通过SMC指令返回BL31,BL31切换到Non-Seucre World继续执行BL33。
BL32 在不同的平台有不同的实现,Intel 的叫做 Software Guard Extensions(SGX),AMD 的叫做 Platform Security Processor(PSP)
BL33
到了BL33这里就是Normal Wrold了,运行的都是非安全固件,也就是我们常见的UEFI firmware或者u-boot,也可能是直接启动Linux kernel。
启动BL1,BL2,BL31,BL32则是一个完整的ATF信任链建立流程(ARM Trusted Firmware),像常见的PSCI(Power State Coordination Interface)功能则是在ATF的BL31上实现。
最后一张图完整展示整个调用流程:
消息摘要算法和加密算法
消息摘要算法
消息摘要又称为数字摘要。它是一个唯一对应一个消息或文本的固定长度的值,它由一个单向Hash加密函数对消息进行作用而产生。
如果消息在途中改变了,则接收者通过对收到消息的新产生的摘要与原摘要比较,就可知道消息是否被改变了。因此消息摘要保证了消息的完整性。
消息摘要采用单向Hash函数,将需加密的明文"摘要"成一串固定位数(如128bit)的密文,这一串密文亦称为数字指纹(Finger Print),它有固定的长度,且不同的明文摘要成密文,其结果总是不同的,而同样的明文其摘要必定一致。
这样这串摘要便可成为验证明文是否是“真身”的“指纹”了。
消息摘要具有不可逆性,在消息摘要生成过程中,会丢失很多原文的信息,而且无法找回。一个好的摘要算法,是极难产生Hash碰撞的,也就是找到另一段明文经计算后产生相同的摘要。
常用的消息摘要算法有MD5,SHA,MAC等。在secure boot中,一般使用sha128,sha256、sha512等算法作为完整性算法。
对于任意长度的消息,sha256都会产生一个256位的哈希值,称作消息摘要。这个摘要相当于是个长度为32个字节的数组,通常有一个长度为64的十六进制字符串来表示,其中1个字节=8位,一个十六进制的字符的长度为4位。
来看一个具体的例子:
TrustChain
这句话经过哈希函数sha256后得到的哈希值为:
3a6fed5fc11392b3ee9f81caf017b48640d7458766a8eb0382899a605b41f2b9
总体上,sha256与MD4、MD5以及HSA-1等哈希函数的操作流程类似,有了消息摘要算法后,我们就可以通过它验证镜像的完整性,从而很容易地就能把被篡改的镜像给识别出来。
加解密算法-RSA
RSA加密是一种非对称加密。可以在不直接传递密钥的情况下,完成解密。这能够确保信息的安全性,避免了直接传递密钥所造成的被破解的风险。
RSA算法是由一对密钥来进行加解密的过程,分别称为公钥和私钥。两者之间有数学相关,该加密算法的原理就是对一极大整数做因数分解的困难性来保证安全性。通常个人保存私钥,公钥是公开的(可能同时多人持有)。
下面以一个例子说明RSA签名的过程。
战场上,B要给A传递一条消息,内容为某一指令。
RSA签名的过程如下:
(1)A生成一对密钥(公钥和私钥),私钥不公开,A自己保留。公钥为公开的,任何人可以获取。
(2)A用自己的私钥对消息加签,形成签名,并将加签的消息和消息本身一起传递给B。
(3)B收到消息后,在获取A的公钥进行验签,如果验签出来的内容与消息本身一致,证明消息是A回复的。
在这个过程中,只有2次传递过程,第一次是A传递加签的消息和消息本身给B,第二次是B获取A的公钥。
即使都被敌方截获,也没有危险性,因为只有A的私钥才能对消息进行签名,即使知道了消息内容,也无法伪造带签名的回复给B,防止了消息内容的篡改。
trustzone & ATF & OPTEE
trustzone
TrustZone是ARM针对消费电子设备设计的一种硬件架构,它对ARM的扩展,其实只是增加了一条指令,一个配置状态位(NS位),以及一个新的有别于核心态和用户态的安全态。其目的是为消费电子产品构建一个安全框架来抵御各种可能的攻击。
TrustZone在概念上将SOC的硬件和软件资源划分为安全(Secure World)和非安全(Normal World)两个世界,所有需要保密的操作在安全世界执行(如指纹识别、密码处理、数据加解密、安全认证等),其余操作在非安全世界执行(如用户操作系统、各种应用程序等),安全世界和非安全世界通过一个名为Monitor Mode的模式进行转换,如图1:
处理器架构上,TrustZone将每个物理核虚拟为两个核,一个非安全核(Non-secure Core, NS Core),运行非安全世界的代码;和另一个安全核(Secure Core),运行安全世界的代码。
两个虚拟的核以基于时间片的方式运行,根据需要实时占用物理核,并通过Monitor Mode在安全世界和非安全世界之间切换,类似同一CPU下的多应用程序环境。
不同的是多应用程序环境下操作系统实现的是进程间切换,而Trustzone下的Monitor Mode实现了同一CPU上两个操作系统间的切换。
OPTEE
OPTEE是一个通常运行在 Secure World EL1 权限中的内核程序,比较常见的是基于开源的 ARM Trusted Firmware 进行扩展修改的,别的实现还有基于 Little Kernel 的,以及一些芯片厂家自己的实现。
它的主要作用是给 Secure World 中运行的程序提供一个基本的系统内核,实现多任务调度、虚拟内存管理、System Call 回调、硬件驱动、IPC 通讯等等。
ATF
TF(Trusted Firmware)是ARM在Armv8引入的安全解决方案,为安全提供了整体解决方案。它包括启动和运行过程中的特权级划分,对Armv7中的TrustZone(TZ)进行了提高,补充了启动过程信任链的传导,细化了运行过程的特权级区间。
TF实际有两种Profile,对ARM Profile A的CPU应用TF-A,对ARM Profile M的CPU应用TF-M。我们一般接触的都是TF-A,又因为这个概念是ARM提出的,有时候也缩写做ATF(ARM Trusted Firmware)。
ATF带来最大的变化是信任链的建立(Trust Chain),整个启动过程包括从EL3到EL0的信任关系的打通。
ATF的启动流程包括5个单独的启动阶段,在不同的异常级别运行,如下表所示。
TrustZone,ATF,OPTEE 这三者有什么关系呢?
TrustZone是一种架构,支持ATF的硬件。ATF是软件,包含bl2 + bl31 + bl32 + bl33,bl32=optee-os,bl33=u-boot。
secure boot启动流程
信任链的构建
由于操作系统启动时可能需要多级启动镜像,而只要其中任意一级镜像未执行secure boot流程,则其后的所有镜像实际上都是不可信的。典型的例子如下:
以上例子中bootrom验证了spl镜像,若spl未验证uboot镜像,则一旦uboot镜像被替换以后,那么攻击者就可以控制后面所有的启动流程。如被替换的uboot可以从其它位置加载非法的linux镜像,而在该linux镜像中任意植入后门等。
因此,secure boot需要建立安全启动的信任链,在启动流程中,每一级镜像都由其前级镜像执行合法性验证。
这样只要保证第一级镜像是合法的,那么第二级镜像的合法性由第一级镜像保证,第三级镜像的合法性由第二级镜像保证。从而像链条一样将整个启动流程的信任链连接起来,最终保证整个系统是可信的。
由于信任链建立流程中,镜像合法性是由其前级镜像验证的,那么第一级镜像的合法性如何保证呢?既然无法由前级镜像为其背书,那么按照惯例,软件没办法解决的问题自然就需要硬件上马了。
我们知道rom是一种只读存储器,它只能被编程一次且内容在其后不能被再次更改。因此若在SOC内部集成一片ROM,并在芯片生产时就将第一级启动镜像刷到这块ROM中,那么也就保证了它是可信的,这也是现代SOC的普遍做法。一般SOC在出厂时就已经在rom固定区域中集成了bootrom镜像,每次芯片启动时都会从bootrom开始执行。
镜像校验方式
下面我们介绍一种常见的镜像签名和校验方法。
- 使用hash算法计算镜像的hash值
- 用私钥将hash值签名后,将签名的结果一起打进镜像中,存放在特定位置。
- 上电后拿到公钥,将存储在镜像中特定位置的hash解密。
- 将解密的hash值与设备中当前计算的hash值做对比,二者一致则校验通过。
总结
以上就介绍了secure boot相关的基本概念和框架,希望大家能对secure boot有更加深刻的理解。secure boot的具体实现方案各个厂家都有所差别,但原理都是相同的。下一篇文章将介绍一种主流的开源的secure boot的实现方案。
本文参考
https://bbs.pediy.com/thread-260399.htm
https://zhuanlan.zhihu.com/p/536007837
https://blog.csdn.net/maybeYoc/article/details/122937844
secure boot (二)基本概念和框架的更多相关文章
- 深入理解Java并发框架AQS系列(二):AQS框架简介及锁概念
深入理解Java并发框架AQS系列(一):线程 深入理解Java并发框架AQS系列(二):AQS框架简介及锁概念 一.AQS框架简介 AQS诞生于Jdk1.5,在当时低效且功能单一的synchroni ...
- 二十七、EFW框架BS系统开发中的MVC模式探讨
回<[开源]EFW框架系列文章索引> EFW框架源代码下载V1.3:http://pan.baidu.com/s/1c0dADO0 EFW框架实例源代码下载:http://p ...
- 反Secure Boot垄断:兼谈如何在Windows 8电脑上安装Linux
感谢HQSQ的投递一.自由软件基金会的呼吁上周,2012年将近结束的时候,自由软件基金会(FSF)发出呼吁,要求人们继续支持反Secure Boot垄断,希望签名者能达到5万人(目前是4万).我觉得, ...
- 小米笔记本怎么关闭secure boot
关闭Secure Boot的步骤: 一.关闭 "快速启动" 功能 1.右键-开始菜单- 电源选项,进入后 点击"选择电源按钮的功能". 2.进入电源选项设置后, ...
- [加密]ESP32 -Secure Boot 安全方案
转自:https://blog.csdn.net/espressif/article/details/79362094 Secure Boot 功能概述 方案概述 Secure Boot 的目的是保证 ...
- 如何在Visual Studio 2017中使用C# 7+语法 构建NetCore应用框架之实战篇(二):BitAdminCore框架定位及架构 构建NetCore应用框架之实战篇系列 构建NetCore应用框架之实战篇(一):什么是框架,如何设计一个框架 NetCore入门篇:(十二)在IIS中部署Net Core程序
如何在Visual Studio 2017中使用C# 7+语法 前言 之前不知看过哪位前辈的博文有点印象C# 7控制台开始支持执行异步方法,然后闲来无事,搞着,搞着没搞出来,然后就写了这篇博文,不 ...
- secure boot(安全启动)下为内核模块签名
上一篇随笔中提到了如何在secure boot下安装Nvidia显卡驱动 >>上一篇随笔 如果不需要安装Nvidia显卡驱动,而且要生成密钥,可以参考>> 这篇文章 这里假设生 ...
- Linux secure boot(安全启动)时添加Nvidia显卡驱动
开启Secure boot情况下,在Fedora 21下安装Nvidia 显卡驱动的方法. Nvidia显卡驱动可以从官网上下载最新版>> 点击进入 下载后添加可执行权限: #chmod ...
- 华硕笔记本之secure boot
在ubuntu下安装cuda的时候,一直装不好,cuda-7.5.run已经装好了,但是编译cuda的例程时失败,提示cuda的库链接不上. 初步判断是secure boot的问题,因为在开启X的情况 ...
- Linux Foundation Secure Boot System Released
As promised, here is the Linux Foundation UEFI secure boot system. This was actually released to us ...
随机推荐
- 0x04.信息收集
探针 被动:借助网上的一些接口查询或者网上已经获取到的,查看历史信息. 主动:使用工具,从本地流量出发,探测目标信息,会发送大量流量到对方服务器上. 谷歌语法 懒人语法:https://pentest ...
- SpringCore完整学习教程6,入门级别
本章从第7章开始: 7. Task Execution and Scheduling 在上下文中没有Executor bean的情况下,Spring Boot会自动配置一个ThreadPoolTask ...
- zookeeper JavaApi 修改节点
*修改数据 * 1.修改数据 * 2.根据版本修改 * * * */ @Test public void testSet() throws Exception{ Stat stat = new Sta ...
- 解决Tensorflow2.0出现:AttributeError: module 'tensorflow' has no attribute 'get_default_graph'的问题
问题描述 在使用tensorflow2.0时,遇到了这个问题: AttributeError: module 'tensorflow' has no attribute 'get_default_gr ...
- DFS遍历图(链式邻接表实现)
1 #include<iostream> 2 #include<string.h> 3 #include<stdlib.h> 4 #include<stdio ...
- 寻找市场中的Alpha—WorldQuant的阿尔法设计理念(上)
本文旨在向读者介绍Alpha的相关基本概念,以及寻找和检验Alpha的主要流程和方法.在上篇中我们梳理了 WorldQuant经典读本FindingAlphas的概要以及WebSim的使用,在下篇中我 ...
- NetSuite 开发日记 —— 库存详细信息记录更改数量问题
详细报错: "type":"error.SuiteScriptError","name":"USER_ERROR",&q ...
- python 图片相关
python 图片相关 本篇介绍两种方式来打开图片. 1: 使用matplotlib #!/usr/bin/python3 # -*- coding: UTF-8 -*- ""&q ...
- pytest框架学习-pytest_addoption钩子函数
适用场景:一套自动化代码,多套环境. pytest_addoption 允许用户自定义注册一个命令行参数,方便用户通过命令行参数的形式给 pytest 传递不同的参数进行不同测试场景的切换. pyte ...
- Date、正则表达式练习
Date.正则表达式练习 package com.guoba.date; import java.text.SimpleDateFormat; import java.util.Calendar; i ...