Sending Policy Commands to Fulfill the Policy
Using the policy session created in the previous step, the code now sends the same sequence of policy commands that it used to create the NV index's policyDigest at Build Entity Policy time; this step corresponds to the Build Policy Digest time interval described previously. In this case, the sequence is very simple, and we only need to send one policy command, a TPM2_PolicyAuthValue command with the following input (lines 177–179):
policySession = Hps.
In response to this command, the TPM does two things:
• It extends the policy session's policy digest just as it did for the trial session at Build Entity Policy time.
• Because TPM2_PolicyAuthValue is a deferred assertion, it saves some state information into the policy session's context so that it knows to check the HMAC at Authorization time.
At this point, the policy authorization is completely “locked and loaded” to authorize the action. The next thing that happens is that we attempt to write to the NV index.
Performing the Action That Requires Authorization
This step corresponds to the Authorization time interval described earlier. We write to the NV index, and, if it's been authorized correctly, the write completes successfully. To do this step, send the TPM2_NV_Write command with the following inputs:
• authHandle = 0x01400001. This handle indicates the source of the authorization. See lines 211-214.
• nvIndex = 0x01400001. This is the NV index to be authorized. See lines 211-214.
• The authorization area for authHandle must have the following settings:
• authHandle = the policy session handle, H . See lines 189-190.
• nonceCaller = whatever nonce the caller wants to use. This can even be a zero-sized nonce. See lines 191-192.
• sessionAttributes = 0. See lines 193-194.
• hmac.t.buffer is set to the HMAC of the command. The HMAC key is the session key concatenated with the authValue of the NV index. See lines 202-205.
• data = 0xa5. See lines 166-169 and 211-214.
• offset = 0. See lines 211-214.
In response to this command, the TPM checks that policySession->policyDigest matches the authPolicy of the entity being accessed. Then it checks that the HMAC is correct. If both checks pass, the write proceeds and the command completes successfully.
■ Note You may have noticed that in Listing 13-2, because the policy case uses a TPM2_PolicyAuthValue command, the hMaC and policy cases are very similar. the main difference is that the policy case requires more work. the obvious question is, if a policy session that uses TPM2_PolicyAuthValue requires more work, why wouldn't we just use an hMaC session? the answer, which is expanded in the next chapter, is that a policy session allows many other factors besides the authorization value to be combined, creating a much more configurable and, possibly, secure authorization.
You've now seen a complete policy authorization from cradle to grave. This was a very simple example, but it should form a good basis for understanding the more complex policy authorizations in the next chapter.
To finish this chapter, we unify the lifecycles for password, HMAC, and policy authorizations into one single lifecycle.