什么是授权?
什么是会话?
这是三种基本的会话形式之一。TPM在进行访问授权时,可根据安全性需要,选择不同形式的会话完成授权。
口令会话是最简单的授权类型:TPM进行授权时,可以通过把明文口令传递到TPM设备中完成任务。口令会话只能用于本地TPM实体访问授权,用于远程授权则会存在安全性问题,因为口令是明文的,无法进行远程传送。
一旦应用程序和TPM设备针对口令达成一致(这是在实体被创建或者实体的授权值被修改时形成的一种共识)后,就再也不需要传输口令了。而在创建实体或者修改实体授权信息时的一次性口令传输也可以以一种安全的方式完成:那就是口令可以用加密形式传输。
一个HMAC会话可以把口令(这个口令在TPM2.0规范中叫做authValue)作为命令和响应计算HMAC时的一个输入参数,从而使授权达到一个很高的安全级别。
在执行一个命令时,调用命令的应用程序会计算HMAC值并将这个值插入到命令字节流中。当TPM收到这个命令字节流后,如果TPM判定HMAC被正确地计算,那么相应的动作就被授权。在响应一个命令时,TPM会计算响应数据的HMAC值然后将这个值插入到响应字节流中。调用命令的应用程序收到命令响应数据流后会再单独计算一次HMAC,然后再与响应字节流中TPM计算的结果对比。如果这两个值匹配,那么响应数据就是可信的。所有的这些过程都是建立在应用程序和TPM都知道并且达成共识的authValue之上的。
HMAC会话会用到两个随机数,又叫作nonce,一个来自于调用者(nonceCaller),另外一个来自TPM(nonceTPM),这两个随机数可以用于防止重放攻击。随机数会用于HMAC的计算中。因为nonceTPM在每次执行命令时都会改变,调用命令的应用程序如果愿意的话也可以在每次执行命令的时候修改nonceCaller,所以攻击者就不能重复使用命令数据流。重复使用的命令字节流用于HMAC计算时一定会失败,这是因为随机数(确切的说是nonceTPM)在重复使用时会变化。
HMAC会话会维护会话生命周期内的状态,因此会话可以用于针对TPM实体的多个动作。启动一个HMAC会话使用TPM2_StartAuthSession命令。当启动会话时,它可以被配置为bound vs. unbound以及salted vs. unsalted会话。这两种选择的组合构成了四种HMAC会话的变量;这四个变量决定了会话密钥和HMAC如何被创建。
策略会话,又被称作增强的授权(Enhanced Authorizaiton),是建立在HMAC会话的基础上的,并且增加了额外的授权级别。HMAC授权仅仅使用授权值或者口令,Policy授权在此基础上做了增强,它可以根据TPM命令的顺序,TPM状态,以及外部设备如指纹读卡器,视网膜扫描器,和智能卡等信息来做授权。多个普通授权条件可以通过AND和OR操作组合成复杂的授权树,从而提供无限多的授权可能。
TPM2.0规范的第3部分对每一个命令都指定了授权角色。授权角色的规则与计算机操作系统中的ACLs(Access Control Lists)的工作方式类似。授权角色控制着与命令执行相关的授权的类型,实际上也就是控制着谁可以在什么情况下执行哪些命令。
一共有三种可能的授权角色:USER,ADMIN,和DUP。USER用于TPM实体的正常使用。ADMIN用于系统管理相关的任务。DUP,一个不常用的角色,主要用在TPM2_Duplicate命令中。
确定实体的授权方式:
决定TPM某个实体授权方式的两个属性是userWithAuth和userWithPolicy。这些属性既可以在创建对象的时候显式地指定,也可以通过特定的永久性handle和NV索引来决定:
如果一个命令的授权角色是ADMIN:
对于TPM对象的handle来说,需要的授权由这个对象的adminWithPolicy属性决定,这个属性是在对象创建的时候设置的。
对于TPM_RH_OWNER,TPM_RH_ENDORSEMENT,以及TPM_RH_PLATFORM这些handle来说,它们的授权相当于adminWithPolicy置为1。也就是说必须通过Policy会话提供授权。
对于NV索引来说,它们的授权相当于创建NV索引时将adminWithPolicy这个属性置为1。
在TPM的命令和响应规范中,包含了一个重要字段—授权域,这个域指定了会话和授权的位置和类型。对于所有需要授权的命令来说,授权区域都会被放置在句柄区域之后以及参数区域之前。命令响应的授权区域被放置在响应的末尾,紧随响应参数之后。
对于任意可以使用授权的命令来说,授权区域最多可以有三个授权结构。对于一个成功执行的TPM2.0命令来说,命令响应的授权结构的数量总是与命令的授权数量相同。对于一个执行失败的TPM2.0命令来说,命令响应的授权数据结构的数量总是0。
如果一个命令的authHandle前面用@符号修饰:这就意味着authHandle对应的实体的授权数据需要加入到这个命令的授权区域中。而“Auth role:USER”表示这个命令需要授权角色。
口令授权生命周期:创建一个使用口令作为授权的实体,然后使用口令对实体相关的动作授权。具体来说,创建和使用口令授权的所需要大概步骤如下:
为了创建一个实体,需要使用以下命令:TPM2_CreatePrimary,TPM2_Create,以及TPM2_NV_DefineSpace。
这几个命令都有一个用户传递authValue的参数,这个authValue就是用于授权的口令。authValue既可以是一个明文口令,也可以是HMAC授权中的输入。
创建不同类型的口令授权实体
如果需要修改一个实体的授权口令,可能需要以下命令:
要使用口令授权,不需要启动会话,调用者只需要填充命令和响应中的信息即可。
HMAC和Policy会话都是由TPM2_StartAuthSession命令来启动的。当会话被启动的时候,它必须是以下几种会话类型之一:HMAC,Policy,或者是Trial Policy。Trial Policy会话是一个功能不健全的Policy会话:它们不能被用于授权任何动作,但是可以用于在创建实体之前生成Policy摘要。
当一个会话启动之后,会话的基本特性已经确定了。具体来说,会话是否绑定、加盐或不加盐、会话密钥的强度,防止重放攻击的强度,参数加解密的强度,以及会话的HMAC强度都通过TPM2_StartAuthSession的参数来确定。
两个handle:
五个参数:
TPM2_StartAuthSession命令运行
1、当一个会话被启动后,TPM会处理命令然后创建一个会话handle,然后计算nonceTPM,以及一个会话密钥。这个会话密钥会用于产生HMAC值,加密命令参数,以及解密命令响应参数。
2、当会话被创建以后,会话密钥就保持不变直到会话结束。会话的handle和nonceTPM将通过命令响应返回。
3、会话密钥将由传递到命令TPM2_StartAuthSession的参数决定,这些参数包括:tpmKey,bind,encryptedSalt,nonceCaller,以及authHash。命令响应的参数,nonceTPM,也被包含在会话密钥中。使用nonceTPM来创建会话密钥可以保证使用相同的authValue,salt,以及nonceCaller将会产生不同的会话密钥。
4、因为调用命令的应用同样也需要会话密钥,所以应用会使用nonceTPM以及其他输入参数复制TPM的计算过程。到现在为止,会话已经启动了,并且调用者和TPM都知道会话密钥。
TPM2_StartAuthSession会话强度
加盐 vs. 不加盐
HMAC和Policy会话都可以是加盐或者不加盐。一个加盐的会话会给会话密钥的创建过程增加更多熵值。一个会话是否加盐取决于TPM2_StartAuthSession的tpmKey参数。使用tpmKey解密后的盐值会被加入到会话密钥的创建过程中。如果authValue的强度很弱,给一个会话加盐有助于防止线下的暴力破解。线下暴力破解是指多次尝试authValue的值看是否可以生成正确的HMAC值。如果破解成功的话,authValue就暴露了。给会话加盐会提高这种类型攻击的门槛。
绑定和非绑定
HMAC和Policy会话都可以是绑定或非绑定的。一个绑定会话就意味着会话被“绑定”到一个特定的TPM实体上,也就是前面提到的“bind”实体;一个绑定会话通常是用于针对“bind”实体授权多次动作。绑定实体的授权值用于计算会话密钥,但是之后就不再需要了。从安全的角度来讲,授权值只使用一次是一个优势,因为调用程序不用一直提示用户输入授权值(口令)或者将授权值存储到内存中。
绑定会话还可以用于针对其他实体(非“bind”实体)的授权,从这个角度来讲,“bind”实体的authValue为会话密钥增加熵值,从而得到更强命令和命令响应参数加解密。bind实体和将要被授权的实体的授权值都会被加入到HMAC的计算中。
一个非绑定会话可以用于授权针对许多不同实体的动作。一个Policy会话通常会被配置成一个非绑定会话。相对于Policy会话提供的安全性来说,HMAC值就没有那么重要了,并且使用Policy会话时不用计算和插入HMAC值将会让授权变得容易很多。
不加盐会话:当bind实体的authValue值确实是足够强到可以生成强度很高的会话密钥和加解密密钥时。如果系统管理员可以强制控制口令的强度时,使用一个unsalted未加盐的会话应该就足够了。
加盐会话:当authValue被认为强度不足以生成安全的会话密钥和加解密密钥时。一个网站可能会向用户请求两种不同的口令:一个是用于加密密钥使用授权,另外一个用于加盐操作。只要使用从密码学上来说足够强的盐值,这两个口令的结合的强度比使用其中一个要强得多。
HMAC和Policy会话的主要不同体现在动作授权的方式上。对于使用HMAC会话发送的命令来说,只有当和命令一起被发送到TPM的HMAC值正确时命令才会成功。为了生成一个正确的HMAC值,命令调用者和TPM之间需要共享一个秘密信息(authValue)。换句话说,计算正确的HMAC值需要知道会话密钥和实体的authValue,这样才能有效地授权实体执行动作。如果不知道会话密钥或者实体的authValue,就不能计算正确的HMAC值,进而导致命令失败。
Policy会话的授权基于一个正确的policy命令序列,在许多情况下还有这些命令成功执行所要求的条件。这仅仅是对这个丰富而又复杂的授权方式的简单描述。
在将要授权的命令执行以前需要有一个Policy命令执行序列。TPM通过检查policyDigest值来确认这个命令执行序列。每一个Policy命令都会将Policy相关的数据的哈希扩展到会话的policyDigest中。最简单的情况就是,将当前会话的policyDigest与被授权实体的policyDigest比较,比较的结果用于决定是否授权相应的命令。
总结下来就是,HAMC授权比口令授权更安全,Policy授权是最丰富也是最复杂的授权。HMAC授权使用事先完全计算好的HMAC值作为证明调用者知道授权秘密信息的方式。Policy授权需要一组Policy命令以及其所需要的一组特定条件来授权一个动作。对于HMAC和Policy授权来说,HMAC值可以用于保证命令和命令响应的完整性。
创建基于HMAC授权的实体包括以下几个步骤:
为了创建一个实体,选择authValue的方法与之前描述的口令授权方式相同。修改已有实体的授权值也是如此。 在这两种操作中,authValue是被同等对待的。
一个HMAC会话是通过将TPM2_StartAuthSession命令的sessionType参数设置成TPM_SE_HAMC来创建的。当HMAC会话启动以后,TPM会根据我们之前的描述创建一个会话密钥。会话密钥是在TPM内部创建的。TPM2_StartAuthSession命令返回之后,调用者会重新创建会话密钥,创建这个密钥会使用bind实体的authValue,salt(盐值),以及通过TPM2_StartAuthSession发送到TPM的参数nonceCaller,还有TPM返回的nonceTPM。
本质上来讲,TPM使用HMAC会话的三个方面来保证命令的安全性:
会话密钥:与会话密钥绑定的authValue和salt应该是只有调用者和TPM设备知道的秘密信息。这两个值都是用于计算会话密钥的。不知道这些值的攻击者就不能计算出会话密钥。因为会话密钥用于创建HMAC密钥,这个特点阻止了中间人攻击。
HMAC:会话密钥和实体的authValue用于生成HMAC密钥。将要被授权的实体的authValue应该只能被调用者和TPM知道。因此,这同样又意味着攻击者不能执行中间人攻击。
Nonces:nonces用于阻止重放攻击。HMAC计算会包含nonce值,如果nonce值不正确的话就没办法计算出正确的HMAC值。又因为nonce值是一直在变化的,所以一次命令的字节流是不能被重复执行的。
只要合理地维护绑定实体的authValue,salt,以及被授权实体的authValue,攻击者就不能对这个实体进行授权。然后一直滚动的nonce值又可以阻止重放攻击。
Session handle:4字节,表示与这个授权内容相关的会话索引值。
Size field:2字节,用于指示Nonce的长度。
Nonce(调用者提供):如果存在,就是调用者设定的一个数值。
Session attributes:一个字节,其中的位域表示了会话的用途。
size of HMAC:2字节,指示authorization区域的大小。
Authorizaiton=HMAC 如果存在的话,它就是一个包含HMAC值得数组。这个HMAC值由调用命令的代码产生。HMAC是由命令的参数计算而来。TPM会独立地计算HMAC值然后和这个HMAC值比较,然后确定TPM收到的命令信息没有被破坏。
Size field:2字节,用于指示Nonce的长度。
Nonce(from TPM):如果存在,就是TPM设定的一个数值。
Session attributes:一个字节,其中的位域表示了会话的用途。
size field = sizeof HMAC:2字节,用于指示acknowledgment区域的大小。
Acknowledgment=HMAC 如果存在的话,它就是一个包含HMAC值得数组。这个HMAC值由TPM产生。HMAC是由命令响应的参数计算而来。命令调用者收到响应数据后会独立地计算HMAC值然后和这个HMAC值比较,然后确定从TPM收到的命令响应信息没有被破坏。