Policy Authorization Lifecycle
The typical steps in a policy authorization lifecycle are very similar, with some additions, to the lifecycle steps used for password and HMAC sessions:
1. Build the entity policy.
2. Create the entity using the policy digest created in step 1.
■ Note steps 1 and 2 are typically performed long before the remaining steps. and the remaining steps can occur multiple times to authorize multiple actions on the entity.
3. Start a policy session.
4. Using the policy session, send policy commands to fulfill the required authorization.
5. Perform the action on the entity that requires authorization.
Let's look at each of these steps in detail, with the applicable line numbers from Listing 13-2. For brevity's sake, line numbers are listed only for code that is unique to policy sessions.
Building the Entity's Policy Digest
The first task in using a policy session is to determine what the authorization policy will be: for example, what entities need to be protected, what actions on those entities need to be restricted, and the exact nature of those restrictions. Then, the policy digest must be created; this step corresponds to the Build Entity Policy time interval described previously. There are two ways to create a policy digest: use a trial policy session, or create the policy digest with software that emulates the actions of the TPM in creating a policy digest. I will describe both of these using a simple example; the code uses a trial policy session.
An example policy might allow an NV index of 0x01400001 to be written or read by someone who knows its authValue. In this case, building the entity policy using a trial policy session can be done as follows:
1. Start a trial policy session using the TPM2_StartAuthSession
command. The main inputs of concern for a policy session are:
a. sessionType = TPM_SE_TRIAL. This is what configures the session as a trial policy session.
b. authHash = TPM_ALG_SHA256. This sets the hashing algorithm used for generating the policyDigest. I chose SHA256, but any hashing algorithm supported by the TPM can be used here.
This command returns a policy session handle, call it Hps. Lines 63, 66, and 72–75 start the trial policy session.
2. Send a TPM2_PolicyAuthValue command with the following inputs (see lines 78–79): policySession = Hps.
This command extends the session's policy digest as follows:
policyDigestnew := HpolicyAlg(policyDigestold || TPM_CC_PolicyAuthValue)
where policyAlg is the hash algorithm set by the TPM2_StartAuthSession command, and policyDigestold is the buffer of length equal to the size of the policy digest that corresponds to the policyAlg with all bytes set to 0.
3. Send a TPM2_GetPolicyDigest command (lines 83–85). This command returns the policy digest, digestps.
Alternatively, to calculate digestps in software, the software needs to duplicate the policy digest calculation in step 2. Appropriate calls to a crypto library such as OpenSSL can be used to accomplish this.
Once the policyDigest has been calculated or created, the NV index can be created to use the policyDigest for authorization of write operations to the index. Unlike a password or HMAC authorization, after the NV index is created the policyDigest used to access an NV index or any other entity can't be directly changed. There are advanced policy commands that can accomplish this through a policy-specific method of indirection, but that topic is described in the next chapter.