【可信计算】第十二次课:TPM授权与会话

一、授权与会话

什么是授权?

  • 授权是TPM2.0规范中的核心概念,TPM所有的规范都在保证对各类资源的访问必须得到授权。授权用于控制对TPM实体的访问,类似于操作系统中的访问控制机制,为TPM提供了安全保障。

什么是会话?

  • 在TPM中,会话与授权紧密联系,有时在概念上会有一些重叠。会话是TPM完成授权的载体和工具。通过设置会话的各种属性和状态来完成各种授权。当然,会话也可以单独完成自己的任务,不用于授权。

1.1 口令会话

这是三种基本的会话形式之一。TPM在进行访问授权时,可根据安全性需要,选择不同形式的会话完成授权。

口令会话是最简单的授权类型:TPM进行授权时,可以通过把明文口令传递到TPM设备中完成任务。口令会话只能用于本地TPM实体访问授权,用于远程授权则会存在安全性问题,因为口令是明文的,无法进行远程传送。

1.2 HMAC会话

一旦应用程序和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如何被创建。

1.3 策略会话

策略会话,又被称作增强的授权(Enhanced Authorizaiton),是建立在HMAC会话的基础上的,并且增加了额外的授权级别。HMAC授权仅仅使用授权值或者口令,Policy授权在此基础上做了增强,它可以根据TPM命令的顺序,TPM状态,以及外部设备如指纹读卡器,视网膜扫描器,和智能卡等信息来做授权。多个普通授权条件可以通过AND和OR操作组合成复杂的授权树,从而提供无限多的授权可能。

1.4 三种策略对比

【可信计算】第十二次课:TPM授权与会话_第1张图片

1.5 授权角色

TPM2.0规范的第3部分对每一个命令都指定了授权角色。授权角色的规则与计算机操作系统中的ACLs(Access Control Lists)的工作方式类似。授权角色控制着与命令执行相关的授权的类型,实际上也就是控制着谁可以在什么情况下执行哪些命令。

一共有三种可能的授权角色:USER,ADMIN,和DUP。USER用于TPM实体的正常使用。ADMIN用于系统管理相关的任务。DUP,一个不常用的角色,主要用在TPM2_Duplicate命令中。

确定实体的授权方式:
决定TPM某个实体授权方式的两个属性是userWithAuth和userWithPolicy。这些属性既可以在创建对象的时候显式地指定,也可以通过特定的永久性handle和NV索引来决定:

  • userWithAuth:
    置为1表示USER角色的授权可以通过口令,HMAC,或者Policy会话提供。
    置为0表示USER角色的授权必须通过Policy会话提供。
  • adminWithPolicy:
    置为1表示ADMIN角色的授权必须通过Policy会话提供。
    置为0表示ADMIN角色的授权可以通过口令,HAMC,或者Policy会话提供。

如果一个命令的授权角色是ADMIN:
对于TPM对象的handle来说,需要的授权由这个对象的adminWithPolicy属性决定,这个属性是在对象创建的时候设置的。
对于TPM_RH_OWNER,TPM_RH_ENDORSEMENT,以及TPM_RH_PLATFORM这些handle来说,它们的授权相当于adminWithPolicy置为1。也就是说必须通过Policy会话提供授权。
对于NV索引来说,它们的授权相当于创建NV索引时将adminWithPolicy这个属性置为1。

1.6 TPM命令中的授权域

在TPM的命令和响应规范中,包含了一个重要字段—授权域,这个域指定了会话和授权的位置和类型。对于所有需要授权的命令来说,授权区域都会被放置在句柄区域之后以及参数区域之前。命令响应的授权区域被放置在响应的末尾,紧随响应参数之后。

对于任意可以使用授权的命令来说,授权区域最多可以有三个授权结构。对于一个成功执行的TPM2.0命令来说,命令响应的授权结构的数量总是与命令的授权数量相同。对于一个执行失败的TPM2.0命令来说,命令响应的授权数据结构的数量总是0。

如果一个命令的authHandle前面用@符号修饰:这就意味着authHandle对应的实体的授权数据需要加入到这个命令的授权区域中。而“Auth role:USER”表示这个命令需要授权角色。
【可信计算】第十二次课:TPM授权与会话_第2张图片
【可信计算】第十二次课:TPM授权与会话_第3张图片
【可信计算】第十二次课:TPM授权与会话_第4张图片
【可信计算】第十二次课:TPM授权与会话_第5张图片
【可信计算】第十二次课:TPM授权与会话_第6张图片
【可信计算】第十二次课:TPM授权与会话_第7张图片

1.7 口令授权

口令授权生命周期:创建一个使用口令作为授权的实体,然后使用口令对实体相关的动作授权。具体来说,创建和使用口令授权的所需要大概步骤如下:

  1. 创建一个使用口令授权的实体,或者修改已有实体的口令值。这个步骤对每一个实体来说只做一次。
  2. 使用口令授权实体相关的动作。这一步骤可以执行多次,并且一旦给实体设定好授权口令后随时都有可能发生。

1.7.1 创建一个口令授权实体

为了创建一个实体,需要使用以下命令:TPM2_CreatePrimary,TPM2_Create,以及TPM2_NV_DefineSpace。

这几个命令都有一个用户传递authValue的参数,这个authValue就是用于授权的口令。authValue既可以是一个明文口令,也可以是HMAC授权中的输入。

创建不同类型的口令授权实体

  • TPM2_CreatePrimary用于创建一个组织架构中的主对象。如果参数inPublic的userWithAuth属性为1,USER授权可以是一个口令授权;使用USER角色的授权动作可以是口令或者HMAC。authValue的值是通过参数inSensitive中的userAuth传递的,现在authValue指的就是口令值。
  • TPM2_Create用于创建可以加载到TPM中的对象。这个命令的授权类型userWithAuth,以及authValue的配置方式都与TPM2_CreatPrimary相同。
  • TPM2_NV_DefineSpace用于定义一个NV索引。如果属性TPMA_NV_AUTHREAD或者TPMA_NV_AUTHWRITE被设置,就可以使用口令授权。输入参数authValue是通过TPM2_NV_DefineSpace的auth参数来传递的。

1.7.2 更改已创建的实体的口令授权

如果需要修改一个实体的授权口令,可能需要以下命令:

  • TPM2_ObjectChangeAuth:它可以用于修改“非”主对象的授权值。
  • TPM2_HierarchyChangeAuth:用于修改一个组织架构的授权值(平台,存储,或者背书),或者是锁定机构的授权值。
  • TPM2_NV_ChangeAuth:用于修改一个NV索引的授权值。

1.7.3 使用口令授权

要使用口令授权,不需要启动会话,调用者只需要填充命令和响应中的信息即可。
【可信计算】第十二次课:TPM授权与会话_第8张图片
【可信计算】第十二次课:TPM授权与会话_第9张图片

1.7.4 开启HMAC和策略会话

HMAC和Policy会话都是由TPM2_StartAuthSession命令来启动的。当会话被启动的时候,它必须是以下几种会话类型之一:HMAC,Policy,或者是Trial Policy。Trial Policy会话是一个功能不健全的Policy会话:它们不能被用于授权任何动作,但是可以用于在创建实体之前生成Policy摘要。

当一个会话启动之后,会话的基本特性已经确定了。具体来说,会话是否绑定、加盐或不加盐、会话密钥的强度,防止重放攻击的强度,参数加解密的强度,以及会话的HMAC强度都通过TPM2_StartAuthSession的参数来确定。

1.7.5 TPM2_StartAuthSession命令特点

两个handle:

  • 如果tpmKey是TPM_RH_NULL,那么这个会话是未加盐的会话;否则,就是加盐的会话,并且encryptedSalt参数将会被TPM解密然后拿到salt值来增加熵值。TPM使用tpmKey这个handle指向的已加载密钥来解密encryptSalt。
  • 如果bind是TPM_RH_NULL,那么这个会话就是unbound会话。否则,就是一个bound会话,并且bind指向的实体的authValue将会和K的salt值连接,K是用于计算sessionKey的HMAC密钥。

五个参数:

  • nonceCaller是第一个随机数,它由调用者设置。这个随机数也决定了后面由TPM返回的随机数的大小。
  • encryptedSalt只有在会话是salted时才会使用,如果会话是unsalted,这个参数必须是空。
  • sessionType决定了会话的类型:HMAC,policy,或者trial policy。
  • symmetric,当会话被设置成encrypt或者decrypt时,它用于指定参数加密的类型。
  • authHash是一个算法ID,这个ID指定了会话的HMAC操作所需的哈希算法。

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会话强度

  • 会话密钥的强度是由bind,tpmKey,encryptedSalt,nonceCaller,以及用于会话的哈希算法共同决定的。
  • 强度最高的会话密钥是通过如下的配置得来的:使用bind指向一个TPM实体(意思是这是一个bound会话),tpmKey指向一个已经加载到TPM的密钥(意思是指这是一个salted会话),nonceCaller的大小设置成哈希算法输出的大小。
  • 如果bind和tpmKey都被设置成TPM_RH_NULL,那结果就是一个长度为0的会话密钥——非常弱的会话密钥。但是,只要实体本身的authValue的强度足够高,那HMAC密钥(实际上就是authValue本身)也是足够强的。
  • 会话中参数nonceCaller的长度决定了nonceTPM的长度。这个随机数越大,会话防止重放攻击的效果就越好。
  • 会话密钥和实体的授权值最终将会用于生成会话的HMAC。所以再次声明,一个高强度的会话密钥和授权值将会带来更好的安全性。
  • 调用TPM2_StartAuthSession的程序员在选择命令参数时需要认真考虑需要什么样的安全属性。

1.8 会话变体

加盐 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被认为强度不足以生成安全的会话密钥和加解密密钥时。一个网站可能会向用户请求两种不同的口令:一个是用于加密密钥使用授权,另外一个用于加盐操作。只要使用从密码学上来说足够强的盐值,这两个口令的结合的强度比使用其中一个要强得多。

1.9 HMAC和策略会话的区别

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值可以用于保证命令和命令响应的完整性

1.10 HMAC授权

创建基于HMAC授权的实体包括以下几个步骤:

  1. 创建一个使用授权值的实体,或者修改已有实体的授权值。对于每一个实体来说,这个步骤通常仅仅执行一次。
  2. 创建一个HMAC会话。
  3. 使用HMAC会话执行基于这个实体的操作。这个操作可以在步骤1和2完成之后的任意时间执行,并且可以执行多次。一个HMAC会话可以用于授权多个动作。

1.10.1修改或者创建一个使用HMAC授权的实体

为了创建一个实体,选择authValue的方法与之前描述的口令授权方式相同。修改已有实体的授权值也是如此。 在这两种操作中,authValue是被同等对待的。

1.10.2 创建一个HMAC会话

一个HMAC会话是通过将TPM2_StartAuthSession命令的sessionType参数设置成TPM_SE_HAMC来创建的。当HMAC会话启动以后,TPM会根据我们之前的描述创建一个会话密钥。会话密钥是在TPM内部创建的。TPM2_StartAuthSession命令返回之后,调用者会重新创建会话密钥,创建这个密钥会使用bind实体的authValue,salt(盐值),以及通过TPM2_StartAuthSession发送到TPM的参数nonceCaller,还有TPM返回的nonceTPM。

1.10.3 使用HMAC会话对单命令授权

【可信计算】第十二次课:TPM授权与会话_第10张图片
HMAC会话单命令授权流程

  1. 输入参数被标准化,连接并组织到一个缓冲区中,叫做cpParams。示例代码的183-185行的Tss2_Sys_NV_Write_Prepare命令会执行这一操作并将cpParams缓冲区放置到sysContext结构中。
  2. 调用者计算cpHash值,这个值是通过对cpParams缓冲区中标准化的命令参数做哈希得来的。示例代码的第202-205行的ComputeCommandHamcs函数会执行这样的操作。
  3. 调用者计算命令的HMAC值。cpHash是这个计算的输入参数之一。这个操作同样也是第202-205行的ComputeCommandHamcs函数来做的。
  4. 计算出来的HMAC值同时还会被ComputeCommandHamcs自动地复制到HAMC会话的HMAC区域中–注意一下这个函数的指针类型的参数nvCmdAuths。
  5. 完整的命令数据必须被标准化并组织到一个字节流中发送到TPM设备。这些数据包括命令头,会话,以及命令参数。参考示例代码的211-214行。
  6. 从TPM中读取命令响应信息。这同样也是在第211-214行的一次调用的函数中执行的。
  7. 接收到命令响应以后,调用者计算rpHash,也就是经过格式化的命令响应参数的哈希值。第224-226行的CheckResponseHmacs函数会执行这个操作。
  8. 调用者计算命令响应的HMAC值,rpHash是这个计算的输入之一。这同样也是第224-226行的CheckResponseHmacs函数来做的。
  9. 调用者比较刚刚计算出的HMAC和命令响应会话中HMAC区域的HMAC值。如果它们不同,那么就认为命令响应参数已经被破坏了,因此这些参数数据都是不可信的。如果两者相同,那就表明命令参数被正确地接收了。这个过程都是由CheckResponseHmacs函数来做的。它会计算命令响应的HMAC值,然后和通过nvRspAuths返回的HMAC值比较。
  10. 如果命令响应的HMAC正确无误,命令响应的参数就可以被反序列化成C语言的结构体以供调用者使用;这个过程也是由211-214行的一次调用函数来执行的。对于这个一次调用的函数来说,需要注意的是,它会假设HMAC值是正确的,并直接将参数反序列化。之后,如果命令响应的HMAC值如果被证明是错的,那就可以忽略已经反序列化的命令响应参数。

1.10.4 HMAC会话安全

本质上来讲,TPM使用HMAC会话的三个方面来保证命令的安全性:

会话密钥:与会话密钥绑定的authValue和salt应该是只有调用者和TPM设备知道的秘密信息。这两个值都是用于计算会话密钥的。不知道这些值的攻击者就不能计算出会话密钥。因为会话密钥用于创建HMAC密钥,这个特点阻止了中间人攻击。

HMAC:会话密钥和实体的authValue用于生成HMAC密钥。将要被授权的实体的authValue应该只能被调用者和TPM知道。因此,这同样又意味着攻击者不能执行中间人攻击。

Nonces:nonces用于阻止重放攻击。HMAC计算会包含nonce值,如果nonce值不正确的话就没办法计算出正确的HMAC值。又因为nonce值是一直在变化的,所以一次命令的字节流是不能被重复执行的。

只要合理地维护绑定实体的authValue,salt,以及被授权实体的authValue,攻击者就不能对这个实体进行授权。然后一直滚动的nonce值又可以阻止重放攻击。

1.10.5 HMAC会话命令授权域

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收到的命令响应信息没有被破坏。

你可能感兴趣的:(笔记,安全)