当前位置:网站首页>【可信计算】第十三次课:TPM扩展授权与密钥管理

【可信计算】第十三次课:TPM扩展授权与密钥管理

2022-07-07 15:39:00 Godams

TPM2.0已经统一了所有由TPM控制的实体的授权方式。前面的章节已经讨论了口令和HMAC授权需要使用的授权数据。这一章将详细讨论TPM的一个新型的而且非常强大的授权方式—扩展授权,也称作策略授权。

策略授权:如果一个用户想限制一个实体只能在某些特定情况下才能被使用,所有针对这个实体使用的限制的总和就叫做一个策略。
在这里插入图片描述

策略授权与口令授权

所有TPM的实体都可以通过两种基本的方式授权。第一个是基于实体创建时期关联的口令,另外一种是实体创建时与该实体相关联的策略。

一些由TPM系统自身创建的实体具有默认的访问口令和策略(如各种基本的组织架构、字典攻击重置句柄)。这样的实体拥有固定的名称,其自身并不依赖于附带的策略,同时这些策略是可以改变的。

很多实体(如NV索引和密钥)的名称是根据它们创建时分配的策略计算哈希得到的,所以访问这些实体的口令可以更改,但是其访问策略不能更改,修改后这个实体的真实性无法通过验证。

任何可以使用口令直接完成的事情也可以通过策略来完成,但是反之则不然,某些事情(如密钥复制)只能只能通过策略完成授权。

策略授权更加灵活,可以对策略进行精细的调整。既可以将策略设置为永远不能满足的NULL策略,也可以通过策略为单独的命令或适用于一个实体的不同用户提供不同的认证方式。

策略授权的优点

允许多种变化的授权(口令,生物信息等等)。
允许多因素授权方式(多于一种的授权类型)。
允许在不使用TPM的情况下创建策略。策略本身不包含任何秘密信息,所以可以完全由软件来创建。但是这并不是说一个策略不需要秘密信息。
允许认证与一个实体相关联的策略。为了使用实体,应该可以证明哪些授权是必要的。
允许多个用户或者角色来满足一个策略。
允许将一个对象的特定角色的功能限制在特定操作或用户。
修正了PCR脆弱的问题。在TPM1.2中,如果一个实体被“锁定”到包含特定配置的一组PCR中,一旦配置必须被更改,那这个实体就不能使用了。

多因素认证

许多不同种类的技术和设备被用于授权。口令是最古老授权方式(或许也是强度最弱的)。生物信息比如说指纹,虹膜扫描,脸部识别,手写签名,甚至是心率都可用于授权。数字签名和HMAC是在令牌或密钥中使用的加密认证形式。银行的时钟把一天中的时间作为授权信息,它不允许在交易时间之外打开金库。

多因素认证是安全的多种表现形式之一,并且它在当今很流行。为了授权执行一个命令,需要执行多种授权方式。这些授权可以有很多种形式——智能卡,口令,生物信息等等。基本的原理就是攻击多种授权比只攻击一种要难。不同类型的授权有不同的优缺点。比如说,口令可以很容易远程提供——但是指纹就没那么容易,尤其实在设计正确的情况下。

口令。
HMAC。
提供数字签名的智能卡。
物理存在/接触(Physical presence)。
机器的状态(PCR)。
TPM的状态(计数器,时间)。
外部设备的状态(指纹读卡器,GPS等等)。

用于认证的每种机制称作断言。

扩展授权的工作原理

一个策略就是一个可以表示一组授权的哈希值,这些授权组合起来可以描述如何满足一个策略。当一个实体(比如说一个密钥)被创建策略的时候,它可能和一个策略关联。为了使用这个实体,用户需要向TPM证明这个策略已经被满足了。

  1. 创建一个策略会话。策略会话被启动时,TPM会为这个会话创建一个会话策略缓冲区。(缓冲区的大小与创建会话时选择的哈希算法相匹配,并且初始化为全0)
  2. 用于通过TPM2_PolicyXXX命令向TPM会话提供一个或者多个授权信息。这些操作会改变会话策略缓冲区的值。这些操作还可能会设置会话的一些标志位,这些标志位用于指示TPM在执行命令时必须执行的一些检查。
  3. 当一个命令使用一个实体时,TPM会比较会话策略缓冲区与实体的授权策略。如果这两者不同,命令就不会被执行。(此时,与策略授权相关的会话标志位也会被检查。如果它们也不满足,这个命令也不会被执行)。

策略不包含任何秘密信息。也就是说,所有的策略都可以使用纯软件的方式在TPM之外创建。但是,为了使用它们,TPM必须能够重新生成这些策略(以会话的策略摘要的形式)。因为TPM有产生策略的能力,所以允许用户使用TPM的这个功能来产生策略就比较合理了。这是通过Trial 策略来实现的。一个Trial 策略不能用于满足一个策略,但是它可以用于计算一个策略的哈希值。

用于满足授权策略的策略会话在某种程度上要比用于创建策略的Trial 策略会话复杂。一些策略命令会立即检查一些断言并更新存储在会话中的策略缓冲区。另外一些命令则会设置标志或者设置会话中的变量,当命令真正被执行时这些标志和变量会被检查。

可创建的策略类型

  • 简单断言策略:使用一个认证方式创建策略。比如口令,智能卡,生物信息,时间等等。
  • 多断言策略:将几种断言结合起来,比如同时要求生物信息和口令;或者智能卡和PIN码;或者口令,智能卡,生物信息,以及GPS位置信息。这样的策略等价于使用AND操作将多种断言组合。
  • 混合策略:这里引入逻辑操作OR,比如说”Bill可以使用一个智能卡授权或者Sally可以使用口令授权“。混合策略可以由任何其他种类的策略组成。
  • 灵活多变的策略:使用通配符或者占位符,具体的授权内容以后定义。一个策略的特定部分可以被其他允许的策略替换。这看起来像是一个简单的断言,但是实际上是任意的(简单或者复杂的)策略都可以替换它。

策略授权的运行原理

一个策略表现为一个哈希值,这个哈希值表现为满足这个策略的方式。一个策略启动时表现为一个缓冲区,缓冲区大小为相关实体的哈希算法对应的哈希长度,缓冲区会被初始化成全0。当部分策略被满足时,这个缓冲区会被扩展能够表示这一事件(具体来说就是策略相关命令的执行)的值。扩展缓冲区的操作就是连接缓冲区当前值和新的数据,然后使用指定的哈希算法对上述的连接结果做哈希,将缓冲区更新成这个哈希值。

简单断言策略

口令或者HMAC(需要向TPM证明,用户知道对象的口令的策略)。
数字签名(智能卡)。
外部设备的认证(一个生物信息读卡器用于验证特定的用户身份,或者一个用于证明机器在特定位置的GPS设备)。
物理存在(是一个类似开关的指示,它可以证明一个用户可以在物理上接触到TPM。尽管这个在规范中有定义,但是很可能不会实现,所以我们后续会忽略这个功能)。
PCR(TPM宿主设备的状态)。
Locality(表示发出TPM命令的软件所在的系统特权级别)。
TPM内部状态(计数器值,定时器的值等等)。

创建断言策略的通用步骤

  1. 创建一个Trial 策略会话,执行下面的命令:
    TPM2_StartAuthSession
    (传递一个参数TPM_SE_TRIAL告知TPM启动一个Trial会话,还需要一个哈希算法的参数用于计算策略的值。该命令会返回会话的handle,可称为myTrialSessionHandle)

  2. 执行描述策略的TPM2策略命令。

  3. 通过执行下面的命令请求TPM创建策略的哈希值
    TPM2_PolicyGetDigest
    这个命令需要传递Trial会话的Handle:myTrialSessionHandle。

  4. 通过执行如下命令来结束会话
    TPM2_FlushContext
    这个命令同样需要传递Trial会话的Handle:myTrialSessionHandle。
    步骤1,3,4对于所有简单的断言是共同的,只有步骤2是独特的。

创建基于口令(明文和HMAC)的断言策略:

  1. 配置策略缓冲区并清零,缓冲区长度设置为哈希算法的输出长度。
    初始化策略值 : 0x0000…0000
  2. 将缓冲区与TPM_CC_PolicyAuthValue连接在一起。
    变化值:0x0000…0000TPM_CC_策略AuthValue
  3. 根据TPM2.0规范第2部分将TPM_CC_PolicyAuthValue替换成对应的数值(示例)
    变化值:0x0000…00000x0000…000016B
  4. 计算上述连接后数值的哈希值,然后将结果置于缓冲区中。这个最终的结果就是一个简单断言的策略值:0x8fcd2169ab92694…1fc7ac1eddc1fddb0e
    在当前例子中,TPM_CC_PolicyAuthValue会被调用者设置为和口令相关的值。

利用HMAC断言进行授权

方法和明文口令类似,只需要设置不同的TPM_CC_PolicyAuthValue。

设置TPM_CC_PolicyAuthValue值

在TPM的会话中设置一个标志用于指示TPM,当一个命令使用的对象需要使用这个策略授权时,需要一个独立的HMAC会话。TPM会检查HAMC值并且与对象的授权值比较,如果匹配才会允许访问。

利用PCR(机器的状态)进行授权

TPM中的PCR通常会被启动前后的软件使用,从而用于表示当前系统运行软件的状态。在TPM1.2的设计中,只有很少一部分功能可以使用这种授权。更槽糕的是,因为使用PCR授权TPM1.2的密钥是一种很脆弱的操作,这个限制也让PCR很难用于授权。

TPM2.0的设计允许包含特定值的PCR用于授权任何命令或者实体。策略只需要指定被引用PCR的序号以及相应的哈希值。另外,TPM2.0包含了多种方式来处理PCR的脆弱性。所有的策略都由一个大小和哈希算法对应的全0缓冲区开始。为了使用PCR断言,策略会被扩展以下值:TPM_CC_PolicyPCR||PCRs selected||digest of the values to be in the PCRs selected。

万一上述的断言通过之后PCR的值发生变化怎么办?在执行TPM_PolicyPCR命令时,TPM会通过记录TPM会话状态中的PCR生成计数器来阻止这样的漏洞。当策略会话正在用于一个命令的授权时,TPM会检查当前PCR的计数器与之前记录的值是否匹配,如果不匹配,那这个会话就不能用于授权。

采用命令的位置进行授权

TPM1.2版本的设计中有一个特性叫做Locality,它用于决定发送到TPM设备的命令来自于什么样的软件栈。TPM1.2中,Locality的主要用途是用于证明CPU处于一个特殊的模式中,这个特殊的模式是指进入Intel TXT或者AMD-V命令模式(这两种模式分别位于Intel和AMD的CPU中)。这些命令主要用于当机器处于不可信的系统运行状态时执行动态信任根测量(DRTM),这样一来就可以可信地报告软件的状态。

在TPM2.0中,就像PCR断言被扩展到任意的授权应用中一样,Locality也被扩展到通用的断言操作中。当策略的一个断言使用Locality时,会话的策略摘要会被扩展以下值:TPM_CC_策略Locality||locality(ies)。

当需要满足一个会话的Locality断言时,用户同样需要使用TPM2_PolicyLocality命令来传递与这个会话绑定的Locality信息。此时会发生以下两件事:

  1. 会话的摘要被扩展以下的值:TPM_CC_PolicyLocality||locality(ies)。
  2. 一个会话的变量被设置成命令的参数Locality。

当用户使用这个会话执行命令时,TPM会比较命令数据中的Locality信息(查看以下PTP规范中的Bit Protocol)和会话之前用变量记录的Locality信息。如果不匹配,命令就不会执行。

Locality可以应用于很多地方。它可以用于表示创建实体的命令的来源。它们还可以用于将一些功能绑定到到特定的软件上。在1.2中,Locality会用于将CPU与复位和扩展特定的PCR绑定在一起(比如PCR17,18),这样是为了在DRTM之前将机器复位成一个已知的状态。SourceForge上的tboot软件展示了它是怎样使用Locality的;来自于CMU的Flicker使用tboot在与OS独立的内存空间内执行安全相关的操作。

因此,Locality会告诉TPM当前这个命令来自于什么软件(或者硬件)。因为TPM本来就知道命令的具体信息(TPM自己在解析命令的时候可以根据Bit Protocol解析出Locality等信息),Locality可以用于授权。

利用TPM的内部状态(引导计数器和计时器)进行授权

TPM1.2设备有一个内部定时器用于测量TPM上次启动到现在经过的时间(这个值可能和外部的时间相关),还有一个内部的单向计数器。但是这两种特性都不能用于授权。TPM2.0有一个定时器,一个时钟,以及启动计数器,它们可以通过复杂的配置方式来提供新的断言。启动计数器用于记录设备已经启动的次数。定时器用于记录TPM设备当次启动后经过的时间。时钟与定时器很像,但是时钟只能向前更新,并且可以被设置成与外部时间相同的值,在TPM掉电以后也就停止工作(这与主板上的RTC就不同了,这个时钟不需要额外的电池供电)。

上述这些特点可以用于限制TPM实体只能在启动计数器没有变化,或者时钟在某一个时间段的情况下使用。实体的使用也可以被限制在白天的时间使用。后者是最有可能的应用场景——将一个计算机的文件访问限制在白天的工作时间内,这有助于阻止黑客在夜晚非法访问文件。

TPM一直都可以检查内部时钟和启动计数器的值,所以它们被成为内部状态。内部状态断言要求在被授权的命令执行之前创建策略会话,并且还要在命令执行之前这些断言是通过的。命令执行时这些断言并不一定通过。

利用NV内存位置进行授权

TPM2.0规范新增加了一个命令,它用于使用特定NVRAM区域存储的值来授权TPM实体的访问。举例来说,如果一个NV索引对应一个32比特的内存区域,你可以使用其中一位的状态来控制TPM实体的访问权限。如果每一个比特都被分配给不同的用户,一个用户访问一个特定实体的权限可以通过修改NVRAM中响应比特的值来撤销或者使能。当然,这也意味着拥有权限写这个NVRAM区域的人拥有最高的密钥使用权限。

这个命令的功能不止于此,因为TPM允许针对NVRAM区域执行逻辑操作。所以你可以设定如下的断言条件:

6 <= NVRAM location < 8 OR 9 < NVRAM location < 23

TPM2.0的NVRAM区域可以被配置成计数器。这就意味着你可以在策略中通过灵活的配置将计数器配置成只能使用n次。

这样的策略需要将策略缓冲区扩展以下的值:TPM_CC_PolicyNV||calculated Value||name of NV location。calculated value表示HASH(value to compare to || offset inito the NVRAM location) || number that represents the operation)

将一个实体看作一个锁,那NVRAM区域中的值就像是锁的制动栓。如果他们的值是正确的,就可以使用这个实体。如果实体内部的状态正确,锁就会被打开。

利用外部设备状态(GPS,指纹识别器)进行授权

TPM2.0设计中最有意思的新的断言方式就是,断言依赖于一个外部设备的状态。这个外部的设备可以代表一个公私密钥对。设备的状态可以是任何可以用它的私钥签名的东西(当然还要结合TPM产生的nonce值)。如果设备是一个生物信息设备,授权的形式可以是“Bob 向我证明了他的身份”。如果设备是一个GPS设备,那就是“我现在的位置是巴尔的摩市”。如果是一个时间服务,断言有可能是“当前的时间是交易时间”。相关的断言会识别代表设备的公钥以及代表设备状态的值(一个签名值)。TPM仅仅是比较签名和期望的鉴定信息。TPM不会对比较的结果做任何进一步计算,所以是(making the representation)设备需要决定它的输入与它签名的内容一致。

这个特点为生物信息提供了灵活性:如果Bob向指纹识别器注册了几个手指的指纹,TPM不需要知道到底是哪一个指纹信息被签名——只需要知道这个指纹对应用户Bob。一个GPS设备不需要特别精确——仅仅是指定的一个区域即可。断言不需要指定一个特别精确的时间,而是指定一个可以接受的时间段就行。但是这个灵活性也不是完全通用的。这不是在说“一些指纹识别器已经证明Bob已经向设备做了身份认证”;而是说“这个特定的指纹识别器已经证明Bob已经向设备做了身份认证”。这个就允许策略的创建者决定使用他信任的生物信息设备,从而防止被轻易地欺骗。

一旦这个策略被满足,就没有进一步的检查了,所以有可能在一个命令执行的时候,相关的断言已经再也不能通过了。

创建这样的策略同样由一个和哈希算法匹配的全0缓冲区开始。然后这个缓冲区会被扩展以下的值:TPM_CC_PolicySigned||SHA256(publicKey)|| stateOfRemoteDevice,stateOfRemoteDevice有两部分组成:描述的大小,和描述本身。

如果使用Trial会话创建这个策略,需要执行TPM2_策略Signed命令。再次说明,必须传递Trial会话的handle,与设备的私钥相对应的公钥handle,远程设备的状态。举例来说,如果远程设备是指纹识别器,它可以对这个信息签名“Sally correctly authenticated”。

使用通配符进行授权

TPM1.2设计的一个主要问题是PCR太脆弱。当一个实体被锁定到一个PCR后,就不能修改PCR的值了。PCR0用于表示BIOS固件,安全性很重要。如果PCR0的值变化了,那可能表示有了安全性漏洞。微软的BitLocker应用就使用它来提供安全性。但是,BIOS固件可能需要升级。当升级完成以后,PCR0的值就会改变,也就使得锁定到旧PCR值的实体再也不能用了。

应用程序可以绕过这个PCR的限制,它是通过在升级BIOS之前将被锁定的密钥解密,然后升级,最后使用新的PCR0的值来锁定密钥。但是这个过程很烦琐,并且在升级BIOS期间这些密钥是处于明文状态的。因此,EA能够允许修改PCR的值但是不用解密锁定的数据这个特点很重要。但是这仍然需要很明显地检查在什么情况下策略可以改变。有很多可能的方案被考虑过,包括增加一个专门用于修改这个策略的授权。

最终的解决方案很机智,它通过使用TPM2_PolicyAuthorize命令来实现,我称这种方法为通配型策略。在玩扑克时,一个通配卡可以替代任何通配卡持有者想要替换的卡。一个通配型的策略同样也可以替换任何持有者想要换的策略。更进一步讲,任何通配策略所有者同意的策略都可以用于满足这个通配型的策略。在创建一个通配型的策略时,可以通过一个wildCardName参数来限制策略。这就是说通配型策略的所有者可以选择具有特定名称的策略可以满足通配型策略。一个与OEM的BIOS签名密钥相关的通配策略理论上可以被任何经过BIOS签名的策略替换。

通配型策略的创建方式与使用外部设备状态的策略类似。通过将策略会话扩展以下内容:TPM_CC_PolicyAuthorize||keySign->nameAlg||keyName||wildCardName。与策略Signed断言一样,如果你使用Trial会话创建通配型的策略,首先需要加载一个公钥到TPM(使用TPM2_LoadExternal命令),然后执行策略Authorize命令。

TPM2_LoadExternal命令会返回已加载公钥的handle,这里叫做aPublicHandle。然后你就可以执行TPM2_策略Authorize,并传递Trial会话的handle,wildCardName,以及aPublicHandle。

TPM2_PolicyAuthorize是TPM中最有用的策略之一,因此它是在对象创建之后可以修改对象策略的唯一方式。这就意味着如果对象已经被锁定到一组PCR值(对应一个特定的系统配置),然后系统的配置发生了变化,对象的策略可以通过这个方式被有效地修改从而与新的配置匹配。

基于命令的断言

尽管这个特性严格来说并不是一个断言,TPM可以限制一个策略只能被特定的命令使用。比如说,你可以限制一个密钥只能用于签名但是不能用于认证其他密钥。如果做了这个限制,策略只能被这个特定的命令使用。通常来说,这个不会限制不会作为一个单独的断言,但是非要这样做技术上也没有问题。在一个密钥的策略中声明这个密钥只能用于签名,那这个密钥既不能认证其他的密钥也不能被其他密钥认证。这是因为当一个密钥在做认证或者被认证时,它需要提供它不能提供的授权。

为了创建这样的策略断言,你首先将与哈希算法匹配的缓冲区初始化为全0。然后使用以下的值扩展:TPM_CC_PolicyCommandCode||the command code to which the Policy is to be restricted。如果是使用Trial会话来创建这个策略,需要执行TPM2_PolicyCommandCode,同时传递Trial会话的handle以及相应的命令代码(command code)。

通常来说,如果你限制一个实体比如密钥只能用于一个命令,你应该也会认证这个命令的使用。这就要求对这个密钥施加不止一种限制,这就是多元素认证的主题了。

使用多因素进行认证授权

TPM知道怎样使用断言来做认证。它还可以使用多个断言来做。举例来说,登录一台PC时,用户可能需要同时提供指纹和智能卡用于身份认证。

我们已经在前面的介绍中看到,策略的创建的过程与PCR扩展的操作类似。它们都有一组全0的值开始(这组值的大小取决于创建策略时选择的哈希算法)。当一个策略命令被调用时,当前策略的值就会被更新,首先在旧值的基础上扩展新参数,然后对这个结果做哈希,最后用新的哈希值替换旧的哈希值。这个操作在PCR中叫做扩展。一个针对策略的逻辑AND操作就是通过在策略上扩展新的断言来实现的。就像一个PCR一样,策略在第一个断言之前是初始化的全0,但是之后断言就会在原有的基础上更新。

授权示例1:智能卡与口令授权
如果你希望在策略中包含一个口令和使用一个密钥签名并且对应公钥为S的智能卡断言,创建策略时,可以首先用以下的值扩展全0的缓冲区:
TPM_CC_PolicySigned||SHA256(publicKey)||0x0000=0x0000060||SHA256(S)||0x0000```
注:最后的0x0000表示你没有为签名提供策略Reference,所以最后的值是2个字节的全零。
然后再扩展口令相关的要求
TPM_CC_PolicyAuthValue=0x0000016B
如果你希望这个命令只能在Locality4中执行,还需要扩展如下的值:
TPM_CC_PolicyLocality||Locality4
扩展一个新的要求等价于执行一个逻辑AND操作。

示例2:利用PC状态、口令和指纹进行授权
Bob创建了一个密钥,它要求PCR1的值为approvedPCRdigest,一个口令,以及一个指纹信息。使用TPM创建这个策略的过程如下:

  1. 启动一个Trial会话。
    使用TPM2_PolicyPCR命令来将策略锁定到approvedPCRdigest。
  2. 使用TPM_PolicyAuthValue命令(指示TPM在命令执行时输入口令)。
  3. 加载指纹识别器的publicKey到TPM中。
  4. 使用TPM2_PolicySigned并传递公钥的handle和stateOfRemoteDevice(也就是“Bob的指纹信息”)。
  5. 从TPM获取策略的值。
  6. 结束会话。

复合策略假设有以下的应用场景:

  1. Dave使用一台机器时使用一个需要指纹和口令的策略来做身份验证。
  2. Dave还可以使用口令和智能卡来做身份验证。
  3. Sally使用智能卡和虹膜扫描器来做身份验证。
  4. IT管理员只能使用密钥复制功能,并且必须在系统的PCR0-5包含已知的值时通过智能卡来授权这个操作。

第一个策略指定Dave必须通过一个外部设备(指纹识别器)来认证自己的身份。然后他还必须提供口令。之前我们已经有相关的介绍,具体的步骤如下:

  1. 启动一个Trial会话。
  2. 执行TPM2_PolicySigned命令(传递指纹识别器的公钥和合适的策略Ref值)。
  3. 执行TPM2_PolicyAuthValue。
  4. 从TPM拿到策略的值,我们称为策略Dave1。
  5. 结束会话。

第二个策略(Dave2)要求Dave输入口令并且使用智能卡签名一个来自TPM的nonce值,从而证明他是智能卡的所有者:

  1. 启动一个Trial会话。
  2. 执行TPM2_PolicyAuthValue。
  3. 执行TPM2_PolicySigned命令(提供智能卡的公钥)。
  4. 从TPM获取策略的值。我们称为策略Dave2。
  5. 结束会话。

第三个策略要求Sally必须首先使用她的智能卡签名一个来自TPM的nonce来证明她是智能卡的授权拥有者,然后通过外部设备来授权她自己,即虹膜扫描仪,从而让外部设备来向TPM证明Sally的身份:

  1. 启动一个Trial会话。
  2. 执行TPM2_PolicySigned命令(使用智能卡的公钥)。
  3. 执行TPM2_PolicySigned命令(提供虹膜扫描仪的公钥和合适的策略Ref)。
  4. 从TPM获取策略的值。我们称为策略Sally。
  5. 结束会话。

最后,IT管理员的策略要求管理员使用它的智能卡签名一个TPM产生的nonce,然后检查PCR0-5在期望的状态。更进一步,IT管理员只能用这个授权做密钥复制:

  1. 启动一个Trial会话。
  2. 执行TPM2_PolicySigned(使用智能卡的公钥)。
  3. 执行TPM2_PolicyPCR(传递选择的PCR,和它们的期望值)。
  4. 执行TPM2_PolicyCommandCode,传递TPM_CC_Duplicate。
  5. 从TPM拿到策略的值。我们称为策略IT。
  6. 结束会话。

密钥管理

使用TPM设计一个密钥管理系统时需要考虑很多事情。如果密钥用于重要的操作,比如加密或者身份认证,使用一个提供标准方法来管理密钥的架构很重要,同时这个架构还要考虑到硬件损坏的情况。这样一个密钥管理架构必须能够处理密钥生成,密钥分发,密钥备份,密钥销毁。

密钥生成

当我们生成一个密钥时,需要考虑的最重要的是密钥是否真得是随机产生的。如果选择了一个比较差的随机数发生器,那么生成的密钥就会不安全。其次就是要考虑保证密钥信息的机密性。TPM被设计成可以免受软件攻击。抗硬件攻击由制造商负责,并不属于TPM设计本身要考虑的范围。TPM的设计允许密钥的分离创建,这是指用于创建密钥的熵在TPM内部和外部都有存储,这样一来,当不使用TPM时,即使有人可以物理上接触到TPM,密钥也是安全的。

密钥在TPM中有三种存在形式。密钥可以由一个种子生成,由TPM的随机数发生器生成,或者被导入到TPM中。主密钥是通过TPM中的种子生成的。用于生成EK的种子与背书密钥组织架构有关,并且终端用户不太可能去修改它。

另一方面,与存储密钥组织架构相关的种子值在TPM收到TPM_Clear命令时就会改变。这个操作可以由使用平台组织架构的BIOS执行,或者由终端用户使用字典攻击复位口令来实现。

主密钥使用FIPS认可的KDF生成,KDF会将主种子和密钥模板组合起来做哈希。密钥生成的模板被分为两部分。第一部分是对密钥类型的描述——是否是一个签名密钥,具体的算法和密钥大小,等等。另外一部分描述的是密钥生成命令用于生成密钥的熵值从哪里来。大多数情况下,第二部分被设置成全0(TCG基础设施工作组公布的EK模板中有)。但是,如果用户不相信TPM内部的熵发生器,他们可以使用这个功能将密钥的熵分开,也就是密钥生成分割。

密钥分割是一个密码学构造,它包含两部分熵——每一部分都有与最终密钥相同的熵值——用于生成密钥。这两个中的任何单独一个都不能提供哪怕是一个比特的最终密钥的熵——所以这两者都是必需的。这样一来,一个可以独立于TPM存储,另外一个则存储在TPM中。

对于一个主密钥来说,一部分分割值是密钥对应组织架构的种子,这存在于TPM中。另外一部分存储在TPM之外的密钥模板中,当不使用时它可以被存储在安全的地方(比方说存储在智能卡中)。

主存储密钥有一个与之关联的对称密钥,它和主存储密钥一起生成。主密钥同样由主种子和外部引进的熵派生而来。只要与组织架构相关的种子没有变化,使用相同的密钥模板总会产生相同的主密钥和相关的对称密钥。因为这两种密钥都使用密钥模板,如果熵由模板提供,那模板中的熵也就是一部分分割的熵。

生成主密钥可能会花费相对较长的时间(如果密钥是RSA密钥),或者是几乎瞬间完成(如果是ECC密钥)。如果密钥生成需要很长时间,用户可能会决定将密钥存储在TPM的持续性内存中,这是通过TPM2_EvictControl命令来实现的,这个命令要求相关的组织架构授权。在这种情况下,密钥就会被分配一个持续性handle,并且重新上电不会影响这个密钥的存在。这个密钥可以使用相同的命令被擦除。用户可以根据所担心攻击的不同,决定是否让密钥变成持续性的密钥。

如果一个用户担心TPM的种子可能已经不安全了,那他们就会担心主密钥也不安全了。如果主密钥不安全了,所有存储在这个主密钥之下的密钥都不安全。在这种情况下,用户可以通过模板使用密钥分割来引入他们自己的熵,并且让密钥变成持续性的密钥,然后将密钥的模板放置在攻击者访问不到的地方。这样就阻止了知道TPM种子的攻击者拿到主密钥秘密信息(没有另外一部分熵)。

标准的密钥模板用于创建密钥,通常情况下使用这些模板比自己创建模板更合理。因为模板会使用强度匹配的算法。在选择对称密钥的时候你可能会使用强度不匹配的算法。TPM2.0使用对称密钥加载其他密钥,而不是像TPM1.2中一样使用非对称密钥。因此,我们可以设计一套系统,系统使用比用于主密钥的非对称密钥强度更高的对称密钥。一旦实现了这样的系统,由TPM产生的密钥就不会面临非对称密钥或者算法强度弱的风险。

密钥树

尽管从技术上来说,可以混用不同的算法——使用一种算法创建一个密钥,然后用一个不同算法的密钥保护这个密钥——这是一个不好的习惯(首先,已经看到了,TSS的FAPI就不允许这样做)。这样做有问题的原因是,一组密钥的整体强度是由其中强度最弱的密钥决定的。这样就意味着,不但不应该混用算法,而且密钥链(就是一个密钥加密后面的密钥,这样组成的链式结构)也应该尽量短。如果密钥链中的任何一个密钥被破坏了,那所有在这个密钥后面的密钥也都被破坏了。所以在面对暴力攻击时,一个由四个密钥组成的密钥链的强度是一个单独密钥的四分之一。

密钥复制

密钥树中,有可能被复制的密钥是个人密钥,企业密钥,金融密钥(个人或者企业),娱乐密钥,HR密钥。为了让密钥可以被复制,在创建密钥时就需要将它们配置成可复制的,并且密钥还需要有一个需要包含TPM2_PolicyCommandCode命令的策略,TPM2_PolicyCommandCode指定的命令为TPM2_Duplicate。在大多数情况下,一个用户会创建两种复制策略——一种用于个人密钥,另外一种用于商业密钥——并将它们分别与一个个人可复制密钥(Personal Duplicable Key)和一个用于商业的可复制密钥(Business Duplicable Key)关联起来。

如果我们不想让一个密钥被复制,可以设置属性为fixedParent。如果一个密钥想独立于它的父密钥SDK或者UDK被复制,那么这个密钥本身也必须有一个可以允许复制的策略。

密钥分发

在某些情况下,一些密钥需要在系统初始配置很久之后分发出去。这时,系统能够安全的分发密钥就显得很重要了。TPM的设计可以让密钥分发变得简单。当每个系统在初始配置时,系统会产生一个不可复制的存储密钥,中央管理系统会记录这个密钥以及密钥所在系统的名称(或者是系统的序列号)。Active Directory或者LDAP数据库可以做这件事情。另外,在本地平台初始配置时,会将中央管理系统中一个签名私钥对应的公钥备份到平台上。

如果中央管理系统想要分发一个HMAC密钥到本地平台时,会执行以下步骤:

  1. 中央管理系统的IT部门使用TPM2_GetRandom创建一个HMAC密钥。
  2. 中央管理系统使用目标系统的存储公钥加密上述的HMAC密钥。
  3. 中央管理系统的IT部分使用自己的签名私钥对加密的HMAC签名。这就让本地系统可以确认它接收到的内容是经过授权的。
  4. 加密的HMAC密钥和相应的签名被发送到本地系统。
  5. 本地系统使用初始配置时备份的中央系统的签名密钥的公钥验证签名。(如果你愿意,可以通过TPM2_LoadExternal加载公钥,然后通过TPM2_VerifySignature来验证签名。)
  6. 本地系统使用TPM2_Import命令将加密的HMAC密钥导入到TPM中,然后得到一个可以加载的,包含HMAC密钥的数据块。
  7. 当用户需要使用HMAC密钥时,本地系统使用TPM_Load命令加载这个HAMC密钥,然后就可以正常使用来。此时,一个本地系统就从中央管理系统得到一个HMAC密钥,并且这个密钥全程没有在本地系统的内存中以明文的方式出现过。

密钥激活

因为TPM拥有从种子创建和重复创建密钥的能力,所以在系统初始配置阶段可以使用多个密钥模板,并由中央IT系统备密钥模板和密钥的公共部分。然后中央IT系统可以重启TPM从而删除系统上的密钥。这样一来,当一个系统被分发到最终的用户时,系统上并没有可用的密钥。之后,当IT想要激活这些密钥时,它只需要向对应的系统发送密钥模板,系统就可以通过TPM2_CreatePrimary命令重新创建密钥。需要注意的是密钥模板中包含密钥的策略,但是没有密钥的口令,口令是在每次重新创建密钥的时候设置的。如果中央IT系统希望避免使用口令授权密钥的访问,它可以通过配置模板中的两个比特位来实现:userWithAuth和adminWith策略。这两个位的设置可以使密钥不能通过口令访问。如果userWithAuth设置位False,并且adminWith策略为True,这样口令就不能做任何事情了。

如果使用上述的技术重新生成密钥,密钥的模板需要包含熵。没有这个模板,密钥就不能被重新创建,因此中央管理系统可以确保客户端在收到模板之前不会使用这个密钥。

还有一种激活密钥的方式,这与TPM1.2的方式类似:使用可迁移的密钥。当一个密钥被复制时,你可以对它双重加密:一次使用新的父密钥加密,一次使用一个对称密钥在复制密令操作完成以后加密。这就产生了一个经过双重加密的数据块。外面一层加密可以由新的父密钥的私钥解密。内层加密使用一个对称密钥。在这种情况下,当我们执行TPM2_Import命令时,TPM必须已经加载新的父密钥的私钥;这个私钥的handle将传递到TPM2_Import命令,同时还有一个秘密信息。这个秘密信息用于计算内层加密的对称密钥,然后用于解密内存加密数据。这个过程如下:

  1. 中央管理系统生成一个可复制密钥。
  2. 使用对称密钥选项复制这个密钥到客户端系统。对称密钥选项是指TPM2_Duplicate函数的encryptionKeyIn参数。
  3. 中央管理系统签名密钥数据块并发送到客户端系统,但是IT要负责安全保存encryptionKeyIn参数。
  4. 当IT管理员想要客户端系统使用这个被复制的密钥时,提供encryptionKeyIn,从而使客户端系统能够通过TPM2_Import命令成功导入密钥。

密钥销毁

一旦密钥被创建以后,有时候能够成功销毁它也很重要。一个例子就是,如果一个用户将要卖掉多余的或者回收再利用一个电脑,并且他希望确保系统上的加密数据和密钥不再可用。TPM提供了多种容易实现的密钥销毁方式。

如果要销毁的是主密钥,最简单的销毁方式就是修改用于创建这个主密钥的密钥组织架构的种子(通常是存储密钥组织架构)。TPM2_Clear可以清除存储密钥组织架构的种子。这个清除TPM的操作会销毁所有与密钥组织架构相关的不可复制密钥,清除密钥组织架构下的所有密钥,并且修改种子,这样就阻止了之前所有与这个组织架构相关的主密钥被重新创建。这个命令还会清除背书密钥组织架构,但是不修改它的种子(EK和设备厂商的证书仍然有效)。可复制的密钥再也不能被加载到系统中,如果它们已经被复制到另外一个系统中,那它们可能没有被删除。

如果一个主密钥是由模板中的熵生成的,并且被配置成持续性密钥的,那么销毁这个密钥需要做的仅仅是销毁密钥模板及其所有副本,然后将主密钥从持续性存储中删除。一旦完成这个操作,这个主密钥就消失了,并且它不能被重新创建。因为不同的主密钥下可以有不同的密钥树,所以这就提供了一种在不影响其他密钥树的情况下销毁一个特定密钥树的方式。当时系统有多个用户在使用同一个TPM时,这种能力显得尤其重要。TPM可以销毁在TPM之外产生的密钥,这些密钥创建以后被导入到TPM并配置成持续性密钥。如果TPM之外的密钥副本被销毁了(这个密钥已经成功地被导入到TPM之后),那仅仅需要将这个密钥从持续性内存中删除就可以销毁这个密钥了。

原网站

版权声明
本文为[Godams]所创,转载请带上原文链接,感谢
https://blog.csdn.net/qq_35481726/article/details/125121849