TPM 2.0规范解读系列——Part 1体系结构第(九)读:PCR状态

前言

TPM 2.0第1部分包含对TPM属性、功能和方法的叙述描述。
本篇主要基于TPM 2.0规范Part 1的第17章(PCR Operations),对PCR(Platform Configuration Register, 平台配置寄存器)的相关操作进行解读。


文章目录

  • 前言
  • 一、PCR初始化(Initializing PCR)
  • 二、PCR的扩展(Extend of a PCR)
  • 三、使用PCR库进行扩展(Using Extend with PCR Banks)
  • 四、事件记录(Recording Events)
  • 五、选择多个PCR(Selecting Multiple PCR)
  • 六、PCR报告(Reporting on PCR)
    • 1、读取PCR
    • 2、证明PCR
  • 七、PCR授权(PCR Authorizations)
    • 1.PCR不在集合中
    • 2.授权集
    • 3.策略集
    • 4.顺序检查
  • 八、PCR分配(PCR Allocation)
  • 九、PCR变更轨迹(PCR Change Tracking)
  • 十、PCR的其它用途(Other Uses for PCR)
  • 总结


一、PCR初始化(Initializing PCR)

在TPM复位和TPM重启时,所有的平台配置寄存器(PCR)被重置为默认的初始条件。 某些PCR可能被TPM Resume指定为保存。 保留的那些将恢复到它们在上次TPM2_Shutdown(STATE)操作时的状态。 当TPM2_Startup()成功完成时,未被TPM Resume指定保存的PCR将处于默认的初始状态。

如果属性允许,PCR也可以通过TPM2_PCR_Reset()或动态可信度量根(D-RTM)序列重置(见34.2)。 PCR属性在特定于平台的规范中定义。 它们确定PCR的重置值以及执行重置所需的位置。

除PCR[0]外,任何PCR的默认初始条件都是所有位CLEAR或所有位SET。 对于PCR[0],默认的初始条件可能是所有位CLEAR、所有位SET、接收到TPM2_Startup()的位置或第一个测量值来自H-CRTM的指示符。 其他平台类型可能使用其他方法来标识访问的位置。

特定于平台的规范可以从上面的选项列表中选择。
例1:某平台特定规范可以指定PCR[0-16]的默认初始条件为全0,PCR[17-20]的默认初始条件为全1。
例2:某平台特定规范可以指定PCR[0]的默认初始条件为位置标识符,PCR[1-16]的初始条件为所有0。
注:“位置标识符”为整型值,取值范围为0到TPM上实现的最大位置。 目前,最大的硬件位置是4。 在TPMA_LOCALITY中,一个4的位置将用八位字节0001 00002表示。 当编码为PCR初始值时,4的位置将由八位字节0000 01002表示。
例3:虚拟TPM可以为每个可能访问它的软件实体使用唯一标识符。 如果特定的软件与特定的PCR相关联,那么该PCR的重置值可能是允许更改它的软件的唯一标识符。

TPM2_PCR_Reset()要求为操作提供适当的授权(见17.7)。

二、PCR的扩展(Extend of a PCR)

除了上面描述的重置外,更改PCR值的唯一方法是扩展它。 对PCR的Extend操作定义为:
PCRnewHalg (PCRold || digest)

在每个Extend之后,对于扩展的摘要值的特定顺序和组合,PCR值是唯一的。

除D-RTM外,扩展PCR需要授权(见17.7)。

三、使用PCR库进行扩展(Using Extend with PCR Banks)

TPM2_PCR_Extend()有一个句柄来指示要扩展的PCR和要扩展的数据。 扩展数据是一种结构,它包含一个或多个摘要以及摘要的算法标识符。 每个摘要被扩展到具有相同算法的PCR库。 如果没有为其中一个PCR库提供摘要数据,则不对该PCR库中的PCR进行更改。

对于每一个定义了pcrNum的算法,TPM都应该执行如下操作:
PCR.digest[pcrNum][alg]newHalg (PCR.digest[pcrNum][alg]old || digest)

其中:
Halg:使用与PCR实例相关联的算法对哈希函数进行哈希处理
PCR.digest:在一个PCR中的摘要值
pcrNum:PCR数值选择器
alg:PCR算法选择器
digest:将列表条目中与PCR库具有相同算法标识符的部分进行摘要
例:如果一个TPM支持三个PCR库(如SHA-1、SHA256和SHA512),一个带有SHA-1摘要和SHA256摘要的到PCR[2]的扩展将在SHA-1库中扩展到PCR[2],在SHA256库中扩展到PCR[2]。 SHA512库中的任何PCR都没有变化。

四、事件记录(Recording Events)

记录日志条目的方法是将完整的日志条目输入到TPM内部,而不是在TPM外部执行摘要。 TPM支持的每种散列算法都可能被用于对日志条目执行散列。 不超过1024个字节的事件可以使用TPM2_PCR_Event()。 超过1024字节的事件可以使用序列命令:TPM2_HashSequenceStart(), TPM2_SequenceUpdate(),和TPM2_EventSequenceComplete())。

TPM2_PCR_Event()和TPM2_EventSequenceComplete()返回一个带标签的摘要列表。 摘要是使用每种实现的散列算法的事件数据摘要。
例:对于实现两种算法(如SHA256和SM3)的TPM,事件命令返回两个带标签的摘要列表。

TPM2_EventSequenceComplete()要求提供适当的授权(见17.7)。

事件的记录也可能是_TPM_Hash_Start/_TPM_Hash_Data/ _TPM_Hash_End序列(H-CRTM事件序列)的结果。 H-CRTM序列的指示来自TPM接口,而不是通过命令缓冲区。 在接收到_TPM_Hash_Start时,TPM将创建一个事件序列上下文。 如果在TPM接收_TPM_Hash_Start时没有可用的对象上下文空间,TPM将刷新上下文(供应商的选择)以创建事件序列上下文。 _TPM_Hash_Data用于更新H-CRTM事件序列上下文,_TPM_Hash_End完成该序列。 H-CRTM事件序列期间计算的摘要或摘要将被扩展到相关平台特异性规范指定的PCR中。 特定于平台的规范可能允许在TPM2_Startup()之前或之后使用H-CRTM事件序列。 TPM2_Startup()之前的H-CRTM事件会影响PCR[0]。 在TPM2_Startup()之后,一个H-CRTM事件影响PCR[17]。

五、选择多个PCR(Selecting Multiple PCR)

TPM2_PCR_Event()隐式选择具有相同索引的所有PCR。 有些命令允许在不同的bank选择多个PCR。 例如TPM2_PCR_Read()、TPM2_Quote()和TPM2_PolicyPCR(),它们允许调用者在多个bank中任意选择PCR。

当一个命令允许选择多个PCR时,将使用一个选择器列表。 列表中的每个条目由一个算法ID后跟一个位数组组成。 位数组中的每个位对应一个PCR。 如果设置了一个位,则选择与算法ID对应的bank中指定的PCR。

与PCR对应的位是PCR[n]对应的位是数组“n/8(向下取整)”八位中的(n mod 8)位。
例:在一个PCR为16的TPM中选择PCR[0]和PCR[13]的阵列为01 2016。 PCR[0]的bit为“0/8(向下取整)”=第0位(0116位),PCR[13]的bit为“13/8(向下取整)”=第5位(2016位)。

选择器列表按顺序处理。 被选中的PCR是串联的,在第一个选择器中编号最低的PCR是列表中的第一个,在最后一个选择器中编号最高的PCR是最后一个。

TPM2_PCR_Read()返回与选择器列表中选择的PCR相对应的PCR值列表。 TPM2_Quote()和TPM2_PolicyPCR()对PCR的串联进行分解。

六、PCR报告(Reporting on PCR)

1、读取PCR

TPM2_PCR_Read()读取选择的PCR的当前值。 对于该命令,调用者使用PCR选择结构指示要读取的PCR列表。 这个结构是一个列表数组。 每个数组条目都有一个哈希标识符和一个位域。 哈希标识符表示PCR的bank,位域表示在bank中选择的PCR。

在响应中,TPM提供了一个PCR选择结构和一个PCR值列表。 PCR选择结构表示返回结构中存在的PCR。 所请求的返回数据结构的大小可能不适合可用的TPM输出缓冲区。 在这种情况下,PCR值列表被截断,响应PCR选择结构指示返回的PCR。 如果返回的结构不包含所有的PCR,调用者可以修改选择结构并发出另一个读请求以获得额外的PCR值。

由于PCR可能在收集所需的全部PCR集合的调用之间改变,TPM返回一个计数器,该计数器在大多数TPM2_PCR_Extend()、TPM2_PCR_Event()、TPM2_EventSequenceComplete()或TPM2_PCR_Reset()的调用中递增(参见17.9的例外情况)。 如果该计数器值在调用之间发生变化,则可能需要重复序列,直到所需的PCR全部返回,而不改变计数器值。

2、证明PCR

在某些情况下,需要将选定的PCR置于特定的状态。 在表示这种状态时,不希望必须列出每个PCR的内容。 相反,一个PCR连接的摘要(一个复合的PCR摘要)将显示所有相关PCR的当前内容。

复合摘要中包含的PCR采用与TPM2_PCR_Read()相同类型的结构选择。 首先对选择结构进行过滤,使未实现的PCR不在选择结构中。 然后,创建所有选定PCR的复合摘要。 最后,对过滤后的选择结构和复合摘要进行散列,以创建最终的摘要值。 该摘要可以与所需的摘要进行比较(TPM2_PolicyPCR())或在认证中返回(TPM2_Quote())。

为了验证证明引用(attestation quote),远程调用者通常会使用PCR重新计算摘要值。 TPM 1.2 quote命令返回PCR值和摘要。 在TPM 2.0中,由于哈希灵活性,PCR集可能已经超过了响应缓冲区的大小。 因此,TPM2_Quote()只返回摘要,并且必须单独检索PCR值。

这可能会导致竞态条件。 在引用的时间和读取它们的时间之间,PCR值可能改变。 有几种解决方案。 PCR可以在引用前后读取,以确保它们没有变化。 另外,在将结果返回给远程调用者之前,可以根据PCR在本地验证引用摘要,并且可以重新运行引用,直到验证成功。

七、PCR授权(PCR Authorizations)

TPM2_PCR_Reset()、TPM2_PCR_Extend()、TPM2_PCR_Event()和TPM2_EventSequenceComplete()需要对修改的PCR进行授权。 根据所修改的PCR,授权的类型可能不同。 PCR可定义为具有固定的EmptyAuth; 一个变量authValue; 或变量authPolicy。

PCR的授权(authValueauthPolicy)可以应用于一组PCR。 也就是说,可以将几个PCR指定为使用相同的授权值,这样,改变集合中任何PCR的授权值(authValue或authPolicy)将改变集合中所有PCR的值。 由authValue授权的一组PCR位于一个授权集中。 由authPolicy授权的一组PCR位于策略集中。

与每个PCR相关联的授权类型由特定于平台的规范固定。 对于每个集合,特定于平台的规范定义了集合中的PCR。 一个PCR不应该位于多个策略集或授权集中。

PCR可以同时存在于策略集和授权集中。 如果两者都是,那么使用授权集的authValue的唯一方法是使用包含TPM2_PolicyAuthValue()或TPM2_PolicyPassword()的策略。

要授权一个PCR,需要正确的授权类型,这将取决于PCR的授权集。 在所有情况下,EmptyAuth值可以在HMAC会话中使用HMAC计算中的零长度authValue提供,也可以作为零长度密码提供。

1.PCR不在集合中

如果PCR不在集合中,授权值可以只有一个EmptyAuth值。

2.授权集

如果PCR在一个授权集中,那么PCR的authValue将以HMAC会话或密码的形式提供。 当PCR具有一个固定的EmptyAuth值时,仍然需要一个授权会话。

当一个PCR有一个变量authValue时,在每次SARTUP(CLEAR)时,该authValue被重置为EmptyAuth。 它被保存在STARTUP(STATE)中。 一个知道authValue的实体可以使用TPM2_PCR_SetAuthValue()来修改变量authValue

3.策略集

策略集的authPolicy具有散列算法和摘要值。

如果authPolicy的散列算法是TPM_ALG_NULL,则该策略还没有设置。 这个未初始化的策略集将使用一个EmptyAuth。

如果策略的摘要算法不是TPM_ALG_NULL,那么策略集是一个初始化的策略集。 如果PCR在一个初始化的策略集中,那么只能通过策略会话授予授权。

TPM2_ChangePPS()将所有策略集的散列算法设置为TPM_ALG_NULL。 与PCR相关联的算法和authPolicy只能由了解平台授权的实体使用TPM2_SetAuthPolicy()来更改。

如果在初始化的策略集中为PCR使用了HMAC会话或密码,那么TPM将返回一个错误(TPM_RC_AUTH_TYPE)。 如果策略会话用于不在初始化策略集中的PCR,那么TPM将返回一个错误(TPM_RC_POLICY_FAIL)。 这两个失败都不会导致字典攻击保护的更新。

4.顺序检查

在为PCR确定正确的授权类型时,TPM将使用该授权类型。 如果授权是密码或HMAC会话,TPM将检查PCR是否在授权集中。

八、PCR分配(PCR Allocation)

TPM可以支持平台重新分配PCR。 要更改PCR的分配,平台将使用TPM2_PCR_Allocate()。 分配结构对每个实现的散列算法都有一个PCR选择。 要在一个bank中分配一个PCR,相应的位将在该bank的选择中被设置。

TPM2_PCR_Allocate()修改的PCR分配将在下一个_TPM_Init生效,并一直持续到下一个TPM2_PCR_Allocate()。
注1:由于RAM的限制,一些实现可能不允许在bank内任意分配PCR。这并没有创建一个部署问题,因为平台预计将能够管理将连接到该平台的TPMs。

如果PCR的属性没有由该TPM的平台特定规范定义,则不能分配PCR。
注2:PCR的属性包括Startup()初始化值、复位的位置和扩展的位置。

有一个要求是每个哈希算法都有一个bank,但不要求bank有任何PCR(也就是说,bank的所有选择的PCR选择位都可以是CLEAR)。

TPM与不可更改的特定PCR分配一起发布是一个有效的实现。 如果TPM不允许更改分配,那么它将不会实现TPM2_PCR_Allocate()。

九、PCR变更轨迹(PCR Change Tracking)

为了支持在策略中使用PCR, TPM维护了一个pcrUpdateCounter。 通常,每次修改PCR(扩展或重置)时,该计数器将增加。 当策略要求PCR具有特定值时使用该计数器(参见19.7.7.6)。

特定于平台的规范可以指定所选PCR的更新不会导致pcrUpdateCounter的变更。

可以使用TPM2_GetCapability(capability == TMP_CAP_PCR_ PROPERTY, property == TPM_PT_PCR_NO_INCREMENT)读取不需要更改pcrUpdateCounter就可以更新的PCR位图。

十、PCR的其它用途(Other Uses for PCR)

这个库中定义的与PCR相关的命令涵盖了常见的用例:例如,在引导期间记录组件或TCB中的运行时切换。 特定于平台的规范定义了控制这种行为的PCR属性,并描述了外部软件应该如何使用PCR。

然而,PCR是为更通用的平台状态表示而设计的,平台特定的规范可能会定义额外的PCR行为来捕捉这一点。 通常,平台规范可以定义一个PCR来表示TPM确信知道的任何值,或者TPM已经安全地通信过的任何值。 例如,用于“可信锁”的TPM可能定义一个PCR,该PCR的值为0,表示门是关闭的,而一个PCR的值表示门是打开的,或者一个虚拟TPM规范可能定义一个PCR,该PCR的值表示发出TPM命令的虚拟机的某些特征。 本规范对这种PCR不要求任何特殊的行为或值-语义。
注:PCR可以通过将PCR设置为该值来“表示”一个值,也可以通过将PCR扩展为该值来“表示”该值。 在“可信锁”的情况下,PCR更可能包含0或1来表示锁的状态,而不是每次对锁的更改都扩展到PCR。

这并不意味着特定于平台的工作组可以定义新的命令来操作PCR。


总结

以上就是今天要讲的内容。本文介绍了PCR操作,PCR最重要操作是初始化(Initializing)、扩展(Extend)和报告(Reporting),还有一些其它功能和用途。

下一篇我们介绍TPM命令/响应结构(TPM Command/Response Structure,Part 1体系结构第18章)。

你可能感兴趣的:(TPM,可信计算,TCM,安全,安全架构,系统安全)