说在前面
本篇文章主要是介绍Strongbox和Weaver的技术架构,其中包含的一些技术细节只是实现方式中的一种,对于不同的硬件环境或者技术策略,还需要OEM和SE发行商之间协定具体的技术流程。这篇文章的主要目的是帮助想要了解Strongbox和Weaver技术细节的开发人员(大多数情况是嵌入式开发人员),快速的了解整个体系框架。
关键词:Keystore, Keymint, Keymaster, TEE, Strongbox, RKP, ROT, Attestation key
一些必要的名词或者概念的解释:
OEM (Original Equipment Manufacturer):这里指手机厂商
SE (Secure Element):安全单元,手机中的安全硬件
REE (Rich Execution Environment): 手机中开发执行环境,无安全性
TEE (Trusted Execution Environment): 可信执行环境,同REE隔离开的安全执行环境
Keymint
Keymint(前身是Keymaster)集成了密钥或者密码操作的各种接口(Java APIs)来支持Keystore应用。其中,Keystore是一个为用户提供密钥保护和保密操作的密钥存储库应用,用户在使用某种加密或者隐私保护功能相关的应用时都会涉及Keystore。Keymint的使用包含了两个关键流程:
** RKP (Remote Key Provisioning)流程:该流程主要用于生成Attestation key,该密钥用于为用户密钥颁发证书。
** ROT (Root of Trust)值 设置流程:ROT值是编译Android镜像时产生的附加信息,ROT值会被TEE通过Strongbox设置到SE中,之后SE在为用户生成密钥时会将ROT值与生成过程绑定,即生成的用户密钥都和ROT值相关。
RKP流程和ROT设置流程的具体细节请查看之后的RKP和ROT章节。
Strongbox
Strongbox是Keymint(只定义接口)部分接口的具体实现(C++实现),提供了以下功能:(1)密码相关功能:加解密,签名验签,密钥生成,密钥协商等;(2)时间戳:基于SE的安全时间戳。下面是Strongbox的架构图。
Weaver
Weaver作为Strongbox的功能之一,用于为LockSettingService和Gatekeeper提供持支持,LockSettingService是一个用户锁屏应用,Andorid通过这种锁定保护来帮助用户保护敏感数据,这种敏感数据尤其指磁盘加密密钥。只有当用户输入Slot对应正确的PIN/Pattern/Password时,用户才能得到该Slot中保存数据的访问权限。如果敌手通过更新Weaver代码来获取敏感数据,敏感数据会被立即擦除。
Weaver底层实现了和增强了Gatekeeper的部分功能,需要注意的是Weaver与Strongbox或SE HAL交互,Gatekeeper和TEE交互,且Weaver主要是对GateKeeper生成的handle做加强保护。具体的认证流程如下:
** 凭证录入(用户设置锁屏密码):
1. 用户输入凭证。
2. LockSettingService从GateKeeper申请一个handle(handle中包含了输入凭证的mac值和其他信息)。
3. LockSettingService使用scrypt算法(一个密钥派生算法)对输入凭证进行计算,生成PWkey,并截取一部分作为Weaver Key。
4. LockSettingService生成一个随机数SR。
5. LockSettingService将Weaver Key和SR和Slot id发送给Weaver Applet进行存储。
6. LockSettingService计算AID = PWkey+SR,并使用Hash(AID)对handle进行加密得到IM。
7. LockSettingService使用system_key对IM加密生成PWblob,并将PWblob存储到REE。
** 用户认证:
1. 用户输入凭证。
2. LockSettingService使用scrypt算法(一个密钥派生算法)对输入凭证进行计算,生成PWkey,并截取一部分作为Weaver Key。
3. LockSettingService 发送Solt id和Weaver Key到Weaver Applet获取SR:(1)如果Weaver Key正确,用户将得到一个秘密值;(2)如果Weaver Key不匹配,则开启允许指数递增时间的解锁尝试流程。
4. LockSettingService使用system_key对PWblob解密得到IM。
5. LockSettingService计算AID = PWkey+SR,并使用Hash(AID)对IMI进行解密得到handle。
6. LockSettingService将handle和PWkey发送到Gatekeeper,Gatekeeper使用PWkey和handle对用户输入的凭证进行验证,如果验证通过,则返回一个AuthToken给用户。
7. 用户通过AuthToken可以派生磁盘加密密钥。
RKP
RKP (Remote Key Provisioning)主要用于生成一组Attestation key(一组公私钥对),用于为用户密钥对签发证书,在使用用户密钥相关功能时,可以通过Attestation key的公钥对用户密钥证书进行验证,确保用户密钥的有效性。具体流程查看RKP流程小节。
RKP于Keymint2.0版本发布时添加,早期的Android设计,OEM需要向Google服务器申请以获取Attestation Key。
Attestation Key
Attestation Key专门用于为Android用户导入的或者用户使用Keymint生成的公钥生成证书。Google规定,Keymint只有在导入Attestation Key后才可以被正常使用。
RKP流程
RKP流程专门用于生成Attestation Key和为Attestation Key申请证书。生成Attestation Key具体的生成流程如下,只有其中的第5步到第11步属于RKP流程,其他属于SE在生产时或者OEM在拿到SE芯片时的预制流程:
1. SE生成自己的HSM Root Key,并从Google服务器为HSM root Key申请证书。HSM Root Key是SE中一组面向Android和Google生成的根密钥,同一批次SE芯片,拥有相同的HSM Root Key。
2. SE生成一组DK Key,并使用HSM Root Pri Key为DK Key进行签名,生成ACC证书链,ACC证书链包含了三级证书,第一级为Google 的根密钥(RSA公钥对)自签名证书,第二级为由Google私钥签名的HSM Root Key证书,第三级为HSM Root Key(P384公钥对)为DK Key(P256公钥对)签名的证书。ACC证书链会在OEM预制过程中和RKP流程中使用。
3. SE厂商将DK Key公私钥对和ACC证书链上传到Google服务器,Google之后会根据该信息判断收到的Attestation Key证书请求来自一家合法厂商。
4. SE 厂商在拿到SE后,先导入DK Key和ACC证书链到SE,ACC证书链用于验证DK Key的合法性。ACC证书链验证通过后,SE内部会使用DK Key的私钥对DK Key进行签名(即自签名)生成BCC证书链。
5. OEM使用SE生成一组Attestation Key(公私钥对),SE返回Maced Attestation Public Key,即Attestation Key的公钥部分以及其mac值,mac值用于验证该公钥确实是由SE生成。
6. OEM输入获取的Maced Attestation Public Key,如果mac值验证通过,SE会生一个临时用于计算hmac值得密钥e_hmac_key。
7. OEM将设备信息DeviceInfo信息导入SE,用于在之后生成CSR(Certificate Signing Request),CSR用于为Attestation Key申请证书。
8. OEM从Google服务器生成挑战值Challenge,用于之后生成CSR。
9. OEM导入EEK证书链到SE,用于之后生成CSR。EEK证书链是谷歌发布,提供给OEM用于申请Attestation Key证书,EEK证书可以Hard Code到TEE或者SE Applet。EEK证书链可能包含了多级证书,但总体包含三级,一级是Google 的EEK根自签名证书,中间的多级证书是使用Google EEK根私钥签名的中间级证书,最后是中间级证书对应的私钥对EEK Key签名生成的证书。
10. 生成CSR:
(1)计算PubKeyToSignMac = HMAC(e_hmac_key, Maced Attestation Public Key)。
(2)使用DK Key对e_hmac_key 进行签名,签名时将(Challenge || PubKeyToSignMac || DeviceInfo)作为附加消息一起进行签名,签名生成SignedMac。
(3)生成临时ECC公私钥对e_ecc_pub和e_ecc_pri,使用该公私钥对和EKK Key进行ECDH密钥协商生成对称密钥session key。
(4)使用session key对ProtectedData=(SignedMac || BCC || ACC)进行加密,加密使用AES-GCM算法,IV内部随机生成,AAD数据为Google官方指定的一组用于指示加密算法的常数值(IV和AAD数据是AES-GCM算法计算的必要数据),即计算Cipher = AES_GCM(session key, IV, ADD, ProtectData)。
(5)将加密生成的数据Cipher ,PubKeyToSignMac,e_ecc_pub,IV等数据一起上传到Google服务器。
11. Google服务器收到Cipher,PubKeyToSignMac,e_ecc_pub和IV等数据后,执行以下流程:(1)首先根据e_ecc_pub和EEK Key进行ECDH密钥协商生成session key;(2)使用session key, IV对Cipher进行解密,同样使用AES-GCM算法,得到ProtectedData;(3)使用之前SE厂商上传到Google服务器的DK key对ProtectedData中的SignedMac进行验签,如果验签成功,则此时Google服务器已经获取了e_hmac_key(计算PubKeyToSignMac 使用的e_hmac_key)。
至此,Google服务器在之后收到OEM发出的CSR时,Google服务器已经能够验证CSR的合法性并为Attestation Key颁发证书(CSR中包含了Attestation Key的公钥和PubKeyToSignMac ,Google服务器可以通过使用e_hmac_key对Attestation Key的公钥计算mac值与PubKeyToSignMac 比较来判断是否要颁发证书)。
ROT
ROT值
ROT值是Android源码编译时生成的一组值,即该值和ROM代码直接相关,每当Android镜像发生更新时,ROT值都会发生变化。ROT值会在每次手机Boot时被设置到SE中,被绑定到用户导入的密钥和申请生成密钥中。每当ROT值发生变化时,之前的密钥都会失效(此时认为已经被攻击)。
ROT值的设置涉及到另一个关键流程,SharedSecret流程。SharedSecret流程用于在TEE和Strongbox之间协商一个对称密钥Hmac key,该密钥会在设置ROT值时使用,TEE在拿到ROT值后,会使用HMAC算法(NIST SP800-108)对ROT值计算mac,然后将ROT值和mac一起传递给Strongbox。之后Strongbox通过mac值和自己持有的Hmac key对ROT值进行验证,只有当验证成功时,才会将ROT值写入SE。
SharedSecret流程和ROT值设置流程参见之后的SharedSecret小节和ROT值设置流程小节。
SharedSecret
SharedSecret是指Andorid会在Boot时,在多个安全应用之间协商一个共有的对称私钥,以此达到之后在对各安全应用之间安全传递数据的目的。本章节主要描述TEE和Strongbox之间进行share secret的过程,需要注意的是,本小节给出的技术细节,会根据硬件条件和其他条件的不同发生变化,例如K值是通过预先协商获得还是预制,如果需要协商K,是否需要预制协商K值使用的私钥Q值等问题(Q值和K值参见下方具体流程中描述)。
本章节以预制Q值,协商K值为例,描述SharedSecret流程,具体如下:
** 协商K:
1. OEM预制Q值到TEE和SE,Q值为AES-GCM加解密计算过程中使用的对称密钥。
2. TEE端生成一个种子S,计算K=KDF(HBK,S)生成K值,KDF为密钥派生算法。
3. 使用对称密钥Q加密K,M=AES-GCM-EN(Q, S||K)。
4. 将M传递给Strongbox,Strongbox使用Q解密M得到S||K,并将S和K存储到flash。
** Share Secret:
1. Android每次启动时,都会调用getSecretParams方法分别从Strongbox和TEE获取Seed||Nonce。
2. Keymint将收到的所有收到的Seed||Nonce进行排列和组合,得到一组参数,将该参数分别发送到TEE和Strongbox。
3. TEE和Strongbox分别计算 Hmac key = HMAC (K, Seed||Nonce...Seed||Nonce,Lable),其中Lable是Google定义的一组常数值。
4. TEE和Strongbox分别使用自己获得的Hmac key对一组常数值计算mac,并分别将mac返回给Keymint。
5. Keymint比较自己收到的多个mac值,如果相同,代表此时Strongbox和TEE已协商和拥有了同一个对称私钥Hmac key。
ROT值设置流程
1. Andorid boot,唤醒TEE和SE。
2. TEE和Strongbox执行SharedSecret流程,如果K值已经生成且存储,则只执行SharedSecret流程中的Share Secret步骤,双方获得Hmac key。
3. TEE从Strongbox申请挑战值challenge,challenge在设置ROT值时使用。
4. TEE从安卓端获取macedROT值,计算mac时,会将challenge作为附加数据一同计算。
5. TEE将macedROT值传递给Strongbox,Stronbox验证mac,如果验证通过,则存储ROT值。
引用
下面的链接中包含了一些具有参考意义的流程图,对理解ROT值的设置流程有很大帮助。
https://blog.youkuaiyun.com/weixin_47139576/article/details/128800543