15679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// This file was extracted from the TCG Published
25679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Trusted Platform Module Library
35679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Part 4: Supporting Routines
45679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Family "2.0"
55679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Level 00 Revision 01.16
65679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// October 30, 2014
75679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
85679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#define SESSION_C
95679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#include "InternalRoutines.h"
105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#include "Platform.h"
115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#include "SessionProcess_fp.h"
125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//           File Scope Function -- ContextIdSetOldest()
155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     This function is called when the oldest contextID is being loaded or deleted. Once a saved context
175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     becomes the oldest, it stays the oldest until it is deleted.
185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     Finding the oldest is a bit tricky. It is not just the numeric comparison of values but is dependent on the
195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     value of contextCounter.
205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     Assume we have a small contextArray with 8, 4-bit values with values 1 and 2 used to indicate the loaded
215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     context slot number. Also assume that the array contains hex values of (0 0 1 0 3 0 9 F) and that the
225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     contextCounter is an 8-bit counter with a value of 0x37. Since the low nibble is 7, that means that values
235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     above 7 are older than values below it and, in this example, 9 is the oldest value.
245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     Note if we subtract the counter value, from each slot that contains a saved contextID we get (- - - - B - 2 -
255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     8) and the oldest entry is now easy to find.
265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
275679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic void
285679752bf24c21135884e987c4077e2f7184897Vadim BendeburyContextIdSetOldest(
295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    void
305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    )
315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    CONTEXT_SLOT         lowBits;
335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    CONTEXT_SLOT         entry;
345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    CONTEXT_SLOT         smallest = ((CONTEXT_SLOT) ~0);
355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    UINT32 i;
365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Set oldestSaveContext to a value indicating none assigned
385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   s_oldestSavedSession = MAX_ACTIVE_SESSIONS + 1;
395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   lowBits = (CONTEXT_SLOT)gr.contextCounter;
405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   for(i = 0; i < MAX_ACTIVE_SESSIONS; i++)
415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       entry = gr.contextArray[i];
435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        // only look at entries that are saved contexts
445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        if(entry > MAX_LOADED_SESSIONS)
455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        {
465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            // Use a less than or equal in case the oldest
475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            // is brand new (= lowBits-1) and equal to our initial
485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            // value for smallest.
495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            if(((CONTEXT_SLOT) (entry - lowBits)) <= smallest)
505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            {
515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                smallest = (entry - lowBits);
525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                s_oldestSavedSession = i;
535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            }
545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        }
555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // When we finish, either the s_oldestSavedSession still has its initial
575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // value, or it has the index of the oldest saved context.
585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//         Startup Function -- SessionStartup()
625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     This function initializes the session subsystem on TPM2_Startup().
645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
655679752bf24c21135884e987c4077e2f7184897Vadim Bendeburyvoid
665679752bf24c21135884e987c4077e2f7184897Vadim BendeburySessionStartup(
675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   STARTUP_TYPE         type
685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32                    i;
715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Initialize session slots. At startup, all the in-memory session slots
725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // are cleared and marked as not occupied
735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   for(i = 0; i < MAX_LOADED_SESSIONS; i++)
745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       s_sessions[i].occupied = FALSE;   // session slot is not occupied
755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // The free session slots the number of maximum allowed loaded sessions
765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   s_freeSessionSlots = MAX_LOADED_SESSIONS;
775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Initialize context ID data. On a ST_SAVE or hibernate sequence, it             will
785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // scan the saved array of session context counts, and clear any entry            that
795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // references a session that was in memory during the state save since            that
805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // memory was not preserved over the ST_SAVE.
815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(type == SU_RESUME || type == SU_RESTART)
825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // On ST_SAVE we preserve the contexts that were saved but not the            ones
845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // in memory
855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       for (i = 0; i < MAX_ACTIVE_SESSIONS; i++)
865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       {
875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           // If the array value is unused or references a loaded session            then
885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           // that loaded session context is lost and the array entry is
895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           // reclaimed.
905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           if (gr.contextArray[i] <= MAX_LOADED_SESSIONS)
915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               gr.contextArray[i] = 0;
925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       }
935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // Find the oldest session in context ID data and set it in
945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // s_oldestSavedSession
955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       ContextIdSetOldest();
965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   else
995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
1005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // For STARTUP_CLEAR, clear out the contextArray
1015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       for (i = 0; i < MAX_ACTIVE_SESSIONS; i++)
1025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           gr.contextArray[i] = 0;
1035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         // reset the context counter
1045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         gr.contextCounter = MAX_LOADED_SESSIONS + 1;
1055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         // Initialize oldest saved session
1065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         s_oldestSavedSession = MAX_ACTIVE_SESSIONS + 1;
1075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
1085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return;
1095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
1105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//           Access Functions
1135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//           SessionIsLoaded()
1155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function test a session handle references a loaded session. The handle must have previously been
1175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      checked to make sure that it is a valid handle for an authorization session.
1185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      NOTE:           A PWAP authorization does not have a session.
1205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      Return Value                       Meaning
1235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      TRUE                               if session is loaded
1255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      FALSE                              if it is not loaded
1265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1275679752bf24c21135884e987c4077e2f7184897Vadim BendeburyBOOL
1285679752bf24c21135884e987c4077e2f7184897Vadim BendeburySessionIsLoaded(
1295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM_HANDLE             handle                // IN: session handle
1305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
1315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
1325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   pAssert(   HandleGetType(handle) == TPM_HT_POLICY_SESSION
1335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           || HandleGetType(handle) == TPM_HT_HMAC_SESSION);
1345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   handle = handle & HR_HANDLE_MASK;
1355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // if out of range of possible active session, or not assigned to a loaded
1365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // session return false
1375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(   handle >= MAX_ACTIVE_SESSIONS
1385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury      || gr.contextArray[handle] == 0
1395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury      || gr.contextArray[handle] > MAX_LOADED_SESSIONS
1405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     )
1415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       return FALSE;
1425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return TRUE;
1435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
1445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//           SessionIsSaved()
1475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function test a session handle references a saved session. The handle must have previously been
1495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      checked to make sure that it is a valid handle for an authorization session.
1505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      NOTE:           An password authorization does not have a session.
1525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function requires that the handle be a valid session handle.
1545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      Return Value                     Meaning
1575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      TRUE                             if session is saved
1595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      FALSE                            if it is not saved
1605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1615679752bf24c21135884e987c4077e2f7184897Vadim BendeburyBOOL
1625679752bf24c21135884e987c4077e2f7184897Vadim BendeburySessionIsSaved(
1635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM_HANDLE            handle                // IN: session handle
1645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
1655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
1665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   pAssert(   HandleGetType(handle) == TPM_HT_POLICY_SESSION
1675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           || HandleGetType(handle) == TPM_HT_HMAC_SESSION);
1685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   handle = handle & HR_HANDLE_MASK;
1695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // if out of range of possible active session, or not assigned, or
1705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // assigned to a loaded session, return false
1715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(   handle >= MAX_ACTIVE_SESSIONS
1725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury      || gr.contextArray[handle] == 0
1735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury      || gr.contextArray[handle] <= MAX_LOADED_SESSIONS
1745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     )
1755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       return FALSE;
1765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return TRUE;
1775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
1785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//           SessionPCRValueIsCurrent()
1815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function is used to check if PCR values have been updated since the last time they were checked in
1835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      a policy session.
1845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function requires the session is loaded.
1855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      Return Value                     Meaning
1875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      TRUE                             if PCR value is current
1895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      FALSE                            if PCR value is not current
1905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1915679752bf24c21135884e987c4077e2f7184897Vadim BendeburyBOOL
1925679752bf24c21135884e987c4077e2f7184897Vadim BendeburySessionPCRValueIsCurrent(
1935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMI_SH_POLICY        handle                // IN: session handle
1945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
1955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
1965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   SESSION                   *session;
1975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   pAssert(SessionIsLoaded(handle));
1985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   session = SessionGet(handle);
1995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(   session->pcrCounter != 0
2005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury      && session->pcrCounter != gr.pcrCounter
2015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     )
2025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       return FALSE;
2035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   else
2045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       return TRUE;
2055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
2065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
2075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
2085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//           SessionGet()
2095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
2105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function returns a pointer to the session object associated with a session handle.
2115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      The function requires that the session is loaded.
2125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
2135679752bf24c21135884e987c4077e2f7184897Vadim BendeburySESSION *
2145679752bf24c21135884e987c4077e2f7184897Vadim BendeburySessionGet(
2155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TPM_HANDLE           handle              // IN: session handle
2165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    )
2175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
2185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    CONTEXT_SLOT        sessionIndex;
2195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    pAssert(   HandleGetType(handle) == TPM_HT_POLICY_SESSION
2205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            || HandleGetType(handle) == TPM_HT_HMAC_SESSION
2215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           );
2225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    pAssert((handle & HR_HANDLE_MASK) < MAX_ACTIVE_SESSIONS);
2235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // get the contents of the session array. Because session is loaded, we
2245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // should always get a valid sessionIndex
2255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    sessionIndex = gr.contextArray[handle & HR_HANDLE_MASK] - 1;
2265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    pAssert(sessionIndex < MAX_LOADED_SESSIONS);
2275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    return &s_sessions[sessionIndex].session;
2285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
2295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
2305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
2315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//           Utility Functions
2325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
2335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//             ContextIdSessionCreate()
2345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
2355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function is called when a session is created. It will check to see if the current gap would prevent a
2365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      context from being saved. If so it will return TPM_RC_CONTEXT_GAP. Otherwise, it will try to find an
2375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      open slot in contextArray, set contextArray to the slot.
2385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This routine requires that the caller has determined the session array index for the session.
2395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
2405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      return type                       TPM_RC
2415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
2425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      TPM_RC_SUCCESS                    context ID was assigned
2435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      TPM_RC_CONTEXT_GAP                can't assign a new contextID until the oldest saved session context is
2445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//                                        recycled
2455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      TPM_RC_SESSION_HANDLE             there is no slot available in the context array for tracking of this
2465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//                                        session context
2475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
2485679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic TPM_RC
2495679752bf24c21135884e987c4077e2f7184897Vadim BendeburyContextIdSessionCreate (
2505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TPM_HANDLE          *handle,             // OUT: receives the assigned handle. This will
2515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                             //     be an index that must be adjusted by the
2525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                             //     caller according to the type of the
2535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                             //     session created
2545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    UINT32               sessionIndex        // IN: The session context array entry that will
2555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                             //     be occupied by the created session
2565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    )
2575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
2585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    pAssert(sessionIndex < MAX_LOADED_SESSIONS);
2595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // check to see if creating the context is safe
2605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // Is this going to be an assignment for the last session context
2615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // array entry? If so, then there will be no room to recycle the
2625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // oldest context if needed. If the gap is not at maximum, then
2635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // it will be possible to save a context if it becomes necessary.
2645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    if(   s_oldestSavedSession < MAX_ACTIVE_SESSIONS
2655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       && s_freeSessionSlots == 1)
2665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    {
2675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        // See if the gap is at maximum
2685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         if(      (CONTEXT_SLOT)gr.contextCounter
2695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               == gr.contextArray[s_oldestSavedSession])
2705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               // Note: if this is being used on a TPM.combined, this return
2715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               //       code should be transformed to an appropriate 1.2 error
2725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               //       code for this case.
2735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               return TPM_RC_CONTEXT_GAP;
2745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
2755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Find an unoccupied entry in the contextArray
2765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   for(*handle = 0; *handle < MAX_ACTIVE_SESSIONS; (*handle)++)
2775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
2785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       if(gr.contextArray[*handle] == 0)
2795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       {
2805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           // indicate that the session associated with this handle
2815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           // references a loaded session
2825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           gr.contextArray[*handle] = (CONTEXT_SLOT)(sessionIndex+1);
2835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           return TPM_RC_SUCCESS;
2845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       }
2855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
2865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return TPM_RC_SESSION_HANDLES;
2875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
2885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
2895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
2905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//           SessionCreate()
2915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
2925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function does the detailed work for starting an authorization session. This is done in a support
2935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      routine rather than in the action code because the session management may differ in implementations.
2945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This implementation uses a fixed memory allocation to hold sessions and a fixed allocation to hold the
2955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      contextID for the saved contexts.
2965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
2975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      Error Returns                   Meaning
2985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
2995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      TPM_RC_CONTEXT_GAP              need to recycle sessions
3005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      TPM_RC_SESSION_HANDLE           active session space is full
3015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      TPM_RC_SESSION_MEMORY           loaded session space is full
3025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
3035679752bf24c21135884e987c4077e2f7184897Vadim BendeburyTPM_RC
3045679752bf24c21135884e987c4077e2f7184897Vadim BendeburySessionCreate(
3055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM_SE               sessionType,        //   IN: the session type
3065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMI_ALG_HASH        authHash,           //   IN: the hash algorithm
3075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B_NONCE         *nonceCaller,        //   IN: initial nonceCaller
3085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMT_SYM_DEF        *symmetric,          //   IN: the symmetric algorithm
3095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMI_DH_ENTITY       bind,               //   IN: the bind object
3105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B_DATA          *seed,               //   IN: seed data
3115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM_HANDLE          *sessionHandle       //   OUT: the session handle
3125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
3135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
3145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM_RC                     result = TPM_RC_SUCCESS;
3155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   CONTEXT_SLOT               slotIndex;
3165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   SESSION                   *session = NULL;
3175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   pAssert(   sessionType == TPM_SE_HMAC
3185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           || sessionType == TPM_SE_POLICY
3195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           || sessionType == TPM_SE_TRIAL);
3205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // If there are no open spots in the session array, then no point in searching
3215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(s_freeSessionSlots == 0)
3225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       return TPM_RC_SESSION_MEMORY;
3235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Find a space for loading a session
3245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   for(slotIndex = 0; slotIndex < MAX_LOADED_SESSIONS; slotIndex++)
3255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
3265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        // Is this available?
3275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        if(s_sessions[slotIndex].occupied == FALSE)
3285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        {
3295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            session = &s_sessions[slotIndex].session;
3305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            break;
3315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        }
3325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
3335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // if no spot found, then this is an internal error
3345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   pAssert (slotIndex < MAX_LOADED_SESSIONS);
3355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Call context ID function to get a handle. TPM_RC_SESSION_HANDLE may be
3365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // returned from ContextIdHandelAssign()
3375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   result = ContextIdSessionCreate(sessionHandle, slotIndex);
3385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(result != TPM_RC_SUCCESS)
3395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       return result;
3405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   //*** Only return from this point on is TPM_RC_SUCCESS
3415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Can now indicate that the session array entry is occupied.
3425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   s_freeSessionSlots--;
3435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   s_sessions[slotIndex].occupied = TRUE;
3445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Initialize the session data
3455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   MemorySet(session, 0, sizeof(SESSION));
3465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Initialize internal session data
3475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   session->authHashAlg = authHash;
3485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Initialize session type
3495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(sessionType == TPM_SE_HMAC)
3505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
3515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       *sessionHandle += HMAC_SESSION_FIRST;
3525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
3535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   else
3545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
3555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       *sessionHandle += POLICY_SESSION_FIRST;
3565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        // For TPM_SE_POLICY or TPM_SE_TRIAL
3575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        session->attributes.isPolicy = SET;
3585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        if(sessionType == TPM_SE_TRIAL)
3595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            session->attributes.isTrialPolicy = SET;
3605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        // Initialize policy session data
3615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        SessionInitPolicyData(session);
3625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
3635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Create initial session nonce
3645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   session->nonceTPM.t.size = nonceCaller->t.size;
3655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   CryptGenerateRandom(session->nonceTPM.t.size, session->nonceTPM.t.buffer);
3665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Set up session parameter encryption algorithm
3675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   session->symmetric = *symmetric;
3685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // If there is a bind object or a session secret, then need to compute
3695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // a sessionKey.
3705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(bind != TPM_RH_NULL || seed->t.size != 0)
3715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
3725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // sessionKey = KDFa(hash, (authValue || seed), "ATH", nonceTPM,
3735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       //                      nonceCaller, bits)
3745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // The HMAC key for generating the sessionSecret can be the concatenation
3755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // of an authorization value and a seed value
3765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       TPM2B_TYPE(KEY, (sizeof(TPMT_HA) + sizeof(seed->t.buffer)));
3775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       TPM2B_KEY            key;
3785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        UINT16                   hashSize;     // The size of the hash used by the
3795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                               // session crated by this command
3805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        TPM2B_AUTH    entityAuth;              // The authValue of the entity
3815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                                     // associated with HMAC session
3825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         // Get hash size, which is also the length of sessionKey
3835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         hashSize = CryptGetHashDigestSize(session->authHashAlg);
3845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         // Get authValue of associated entity
3855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         entityAuth.t.size = EntityGetAuthValue(bind, &entityAuth.t.buffer);
3865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         // Concatenate authValue and seed
3875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         pAssert(entityAuth.t.size + seed->t.size <= sizeof(key.t.buffer));
3885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         MemoryCopy2B(&key.b, &entityAuth.b, sizeof(key.t.buffer));
3895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         MemoryConcat2B(&key.b, &seed->b, sizeof(key.t.buffer));
3905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         session->sessionKey.t.size = hashSize;
3915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         // Compute the session key
3925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         KDFa(session->authHashAlg, &key.b, "ATH", &session->nonceTPM.b,
3935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              &nonceCaller->b, hashSize * 8, session->sessionKey.t.buffer, NULL);
3945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
3955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Copy the name of the entity that the HMAC session is bound to
3965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Policy session is not bound to an entity
3975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(bind != TPM_RH_NULL && sessionType == TPM_SE_HMAC)
3985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
3995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       session->attributes.isBound = SET;
4005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       SessionComputeBoundEntity(bind, &session->u1.boundEntity);
4015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
4025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // If there is a bind object and it is subject to DA, then use of this session
4035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // is subject to DA regardless of how it is used.
4045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   session->attributes.isDaBound =    (bind != TPM_RH_NULL)
4055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                   && (IsDAExempted(bind) == FALSE);
4065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // If the session is bound, then check to see if it is bound to lockoutAuth
4075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   session->attributes.isLockoutBound =    (session->attributes.isDaBound == SET)
4085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                        && (bind == TPM_RH_LOCKOUT);
4095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return TPM_RC_SUCCESS;
4105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
4115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
4125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
4135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//           SessionContextSave()
4145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
4155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function is called when a session context is to be saved. The contextID of the saved session is
4165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      returned. If no contextID can be assigned, then the routine returns TPM_RC_CONTEXT_GAP. If the
4175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      function completes normally, the session slot will be freed.
4185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function requires that handle references a loaded session. Otherwise, it should not be called at the
4195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      first place.
4205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
4215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      Error Returns                      Meaning
4225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
4235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      TPM_RC_CONTEXT_GAP                 a contextID could not be assigned.
4245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      TPM_RC_TOO_MANY_CONTEXTS           the counter maxed out
4255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
4265679752bf24c21135884e987c4077e2f7184897Vadim BendeburyTPM_RC
4275679752bf24c21135884e987c4077e2f7184897Vadim BendeburySessionContextSave (
4285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM_HANDLE                 handle,           // IN: session handle
4295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   CONTEXT_COUNTER           *contextID         // OUT: assigned contextID
4305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
4315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
4325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32                            contextIndex;
4335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   CONTEXT_SLOT                      slotIndex;
4345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   pAssert(SessionIsLoaded(handle));
4355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // check to see if the gap is already maxed out
4365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Need to have a saved session
4375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(   s_oldestSavedSession < MAX_ACTIVE_SESSIONS
4385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         // if the oldest saved session has the same value as the low bits
4395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         // of the contextCounter, then the GAP is maxed out.
4405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury      && gr.contextArray[s_oldestSavedSession] == (CONTEXT_SLOT)gr.contextCounter)
4415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       return TPM_RC_CONTEXT_GAP;
4425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // if the caller wants the context counter, set it
4435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(contextID != NULL)
4445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       *contextID = gr.contextCounter;
4455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   pAssert((handle & HR_HANDLE_MASK) < MAX_ACTIVE_SESSIONS);
4465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   contextIndex = handle & HR_HANDLE_MASK;
4475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Extract the session slot number referenced by the contextArray
4485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // because we are going to overwrite this with the low order
4495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // contextID value.
4505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   slotIndex = gr.contextArray[contextIndex] - 1;
4515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Set the contextID for the contextArray
4525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   gr.contextArray[contextIndex] = (CONTEXT_SLOT)gr.contextCounter;
4535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Increment the counter
4545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   gr.contextCounter++;
4555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // In the unlikely event that the 64-bit context counter rolls over...
4565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(gr.contextCounter == 0)
4575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
4585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // back it up
4595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       gr.contextCounter--;
4605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // return an error
4615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       return TPM_RC_TOO_MANY_CONTEXTS;
4625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
4635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // if the low-order bits wrapped, need to advance the value to skip over
4645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // the values used to indicate that a session is loaded
4655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(((CONTEXT_SLOT)gr.contextCounter) == 0)
4665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       gr.contextCounter += MAX_LOADED_SESSIONS + 1;
4675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // If no other sessions are saved, this is now the oldest.
4685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(s_oldestSavedSession >= MAX_ACTIVE_SESSIONS)
4695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       s_oldestSavedSession = contextIndex;
4705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Mark the session slot as unoccupied
4715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   s_sessions[slotIndex].occupied = FALSE;
4725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // and indicate that there is an additional open slot
4735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   s_freeSessionSlots++;
4745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return TPM_RC_SUCCESS;
4755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
4765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
4775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
4785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//           SessionContextLoad()
4795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
4805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function is used to load a session from saved context. The session handle must be for a saved
4815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      context.
4825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      If the gap is at a maximum, then the only session that can be loaded is the oldest session, otherwise
4835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      TPM_RC_CONTEXT_GAP is returned.
4845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function requires that handle references a valid saved session.
4855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
4865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
4875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
4885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      Error Returns                   Meaning
4895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
4905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      TPM_RC_SESSION_MEMORY           no free session slots
4915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      TPM_RC_CONTEXT_GAP              the gap count is maximum and this is not the oldest saved context
4925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
4935679752bf24c21135884e987c4077e2f7184897Vadim BendeburyTPM_RC
4945679752bf24c21135884e987c4077e2f7184897Vadim BendeburySessionContextLoad(
4955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   SESSION            *session,            // IN: session structure from saved context
4965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM_HANDLE         *handle              // IN/OUT: session handle
4975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
4985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
4995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32                    contextIndex;
5005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   CONTEXT_SLOT              slotIndex;
5015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   pAssert(   HandleGetType(*handle) == TPM_HT_POLICY_SESSION
5025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           || HandleGetType(*handle) == TPM_HT_HMAC_SESSION);
5035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Don't bother looking if no openings
5045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(s_freeSessionSlots == 0)
5055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       return TPM_RC_SESSION_MEMORY;
5065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Find a free session slot to load the session
5075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   for(slotIndex = 0; slotIndex < MAX_LOADED_SESSIONS; slotIndex++)
5085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       if(s_sessions[slotIndex].occupied == FALSE) break;
5095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // if no spot found, then this is an internal error
5105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   pAssert (slotIndex < MAX_LOADED_SESSIONS);
5115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   contextIndex = *handle & HR_HANDLE_MASK;               // extract the index
5125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // If there is only one slot left, and the gap is at maximum, the only session
5135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // context that we can safely load is the oldest one.
5145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(   s_oldestSavedSession < MAX_ACTIVE_SESSIONS
5155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury      && s_freeSessionSlots == 1
5165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury      && (CONTEXT_SLOT)gr.contextCounter == gr.contextArray[s_oldestSavedSession]
5175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury      && contextIndex != s_oldestSavedSession
5185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     )
5195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       return TPM_RC_CONTEXT_GAP;
5205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   pAssert(contextIndex < MAX_ACTIVE_SESSIONS);
5215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // set the contextArray value to point to the session slot where
5225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // the context is loaded
5235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   gr.contextArray[contextIndex] = slotIndex + 1;
5245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // if this was the oldest context, find the new oldest
5255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(contextIndex == s_oldestSavedSession)
5265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       ContextIdSetOldest();
5275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Copy session data to session slot
5285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   s_sessions[slotIndex].session = *session;
5295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Set session slot as occupied
5305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   s_sessions[slotIndex].occupied = TRUE;
5315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Reduce the number of open spots
5325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   s_freeSessionSlots--;
5335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return TPM_RC_SUCCESS;
5345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
5355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
5365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
5375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
5385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//           SessionFlush()
5395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
5405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function is used to flush a session referenced by its handle. If the session associated with handle is
5415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      loaded, the session array entry is marked as available.
5425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function requires that handle be a valid active session.
5435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
5445679752bf24c21135884e987c4077e2f7184897Vadim Bendeburyvoid
5455679752bf24c21135884e987c4077e2f7184897Vadim BendeburySessionFlush(
5465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TPM_HANDLE           handle             // IN: loaded or saved session handle
5475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    )
5485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
5495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    CONTEXT_SLOT              slotIndex;
5505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    UINT32                    contextIndex;       // Index into contextArray
5515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    pAssert(      (    HandleGetType(handle) == TPM_HT_POLICY_SESSION
5525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                    || HandleGetType(handle) == TPM_HT_HMAC_SESSION
5535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  )
5545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               && (SessionIsLoaded(handle) || SessionIsSaved(handle))
5555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              );
5565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // Flush context ID of this session
5575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // Convert handle to an index into the contextArray
5585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    contextIndex = handle & HR_HANDLE_MASK;
5595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    pAssert(contextIndex < sizeof(gr.contextArray)/sizeof(gr.contextArray[0]));
5605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // Get the current contents of the array
5615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    slotIndex = gr.contextArray[contextIndex];
5625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // Mark context array entry as available
5635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    gr.contextArray[contextIndex] = 0;
5645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // Is this a saved session being flushed
5655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    if(slotIndex > MAX_LOADED_SESSIONS)
5665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    {
5675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        // Flushing the oldest session?
5685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        if(contextIndex == s_oldestSavedSession)
5695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            // If so, find a new value for oldest.
5705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            ContextIdSetOldest();
5715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    }
5725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    else
5735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    {
5745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        // Adjust slot index to point to session array index
5755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        slotIndex -= 1;
5765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         // Free session array index
5775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         s_sessions[slotIndex].occupied = FALSE;
5785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         s_freeSessionSlots++;
5795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    }
5805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    return;
5815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
5825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
5835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
5845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//           SessionComputeBoundEntity()
5855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
5865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function computes the binding value for a session. The binding value for a reserved handle is the
5875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      handle itself. For all the other entities, the authValue at the time of binding is included to prevent
5885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      squatting. For those values, the Name and the authValue are concatenated into the bind buffer. If they
5895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      will not both fit, the will be overlapped by XORing() bytes. If XOR is required, the bind value will be full.
5905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
5915679752bf24c21135884e987c4077e2f7184897Vadim Bendeburyvoid
5925679752bf24c21135884e987c4077e2f7184897Vadim BendeburySessionComputeBoundEntity(
5935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TPMI_DH_ENTITY      entityHandle,     // IN: handle of entity
5945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TPM2B_NAME         *bind              // OUT: binding value
5955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    )
5965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
5975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TPM2B_AUTH               auth;
5985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    INT16                    overlap;
5995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // Get name
600e85c65bf85bc6251895cdfe6bb6213d125cc2366ChromeOS Developer    bind->t.size = EntityGetName(entityHandle, &bind->t.name);
6015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     // The bound value of a reserved handle is the handle itself
6025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     if(bind->t.size == sizeof(TPM_HANDLE)) return;
6035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // For all the other entities, concatenate the auth value to the name.
6045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // Get a local copy of the auth value because some overlapping
6055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // may be necessary.
6065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    auth.t.size = EntityGetAuthValue(entityHandle, &auth.t.buffer);
6075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    pAssert(auth.t.size <= sizeof(TPMU_HA));
6085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // Figure out if there will be any overlap
609e85c65bf85bc6251895cdfe6bb6213d125cc2366ChromeOS Developer    overlap = bind->t.size + auth.t.size - sizeof(bind->t.name);
6105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // There is overlap if the combined sizes are greater than will fit
6115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    if(overlap > 0)
6125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    {
6135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        // The overlap area is at the end of the Name
614e85c65bf85bc6251895cdfe6bb6213d125cc2366ChromeOS Developer        BYTE    *result = &bind->t.name[bind->t.size - overlap];
6155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        int     i;
6165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         // XOR the auth value into the Name for the overlap area
6175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         for(i = 0; i < overlap; i++)
6185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             result[i] ^= auth.t.buffer[i];
6195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    }
6205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    else
6215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    {
6225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        // There is no overlap
6235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        overlap = 0;
6245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    }
6255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    //copy the remainder of the authData to the end of the name
626e85c65bf85bc6251895cdfe6bb6213d125cc2366ChromeOS Developer    MemoryCopy(&bind->t.name[bind->t.size], &auth.t.buffer[overlap],
627e85c65bf85bc6251895cdfe6bb6213d125cc2366ChromeOS Developer               auth.t.size - overlap, sizeof(bind->t.name) - bind->t.size);
6285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // Increase the size of the bind data by the size of the auth - the overlap
6295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    bind->t.size += auth.t.size-overlap;
6305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    return;
6315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
6325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
6335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
6345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//           SessionInitPolicyData()
6355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
6365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function initializes the portions of the session policy data that are not set by the allocation of a
6375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      session.
6385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
6395679752bf24c21135884e987c4077e2f7184897Vadim Bendeburyvoid
6405679752bf24c21135884e987c4077e2f7184897Vadim BendeburySessionInitPolicyData(
6415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    SESSION            *session           // IN: session handle
6425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    )
6435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
6445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // Initialize start time
6455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    session->startTime = go.clock;
6465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // Initialize policyDigest. policyDigest is initialized with a string of 0 of
6475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // session algorithm digest size. Since the policy already contains all zeros
6485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // it is only necessary to set the size
6495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     session->u2.policyDigest.t.size = CryptGetHashDigestSize(session->authHashAlg);
6505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     return;
6515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
6525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
6535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
6545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//           SessionResetPolicyData()
6555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
6565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function is used to reset the policy data without changing the nonce or the start time of the session.
6575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
6585679752bf24c21135884e987c4077e2f7184897Vadim Bendeburyvoid
6595679752bf24c21135884e987c4077e2f7184897Vadim BendeburySessionResetPolicyData(
6605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     SESSION            *session             // IN: the session to reset
6615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     )
6625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
6635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     session->commandCode = 0;              // No command
6645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     // No locality selected
6655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     MemorySet(&session->commandLocality, 0, sizeof(session->commandLocality));
6665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     // The cpHash size to zero
6675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     session->u1.cpHash.b.size = 0;
6685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     // No timeout
6695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     session->timeOut = 0;
6705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     // Reset the pcrCounter
6715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     session->pcrCounter = 0;
6725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     // Reset the policy hash
6735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     MemorySet(&session->u2.policyDigest.t.buffer, 0,
6745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               session->u2.policyDigest.t.size);
6755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     // Reset the session attributes
6765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     MemorySet(&session->attributes, 0, sizeof(SESSION_ATTRIBUTES));
6775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     // set the policy attribute
6785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     session->attributes.isPolicy = SET;
6795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
6805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
6815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
6825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//           SessionCapGetLoaded()
6835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
6845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function returns a list of handles of loaded session, started from input handle
6855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      Handle must be in valid loaded session handle range, but does not have to point to a loaded session.
6865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
6875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      Return Value                      Meaning
6885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
6895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      YES                               if there are more handles available
6905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      NO                                all the available handles has been returned
6915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
6925679752bf24c21135884e987c4077e2f7184897Vadim BendeburyTPMI_YES_NO
6935679752bf24c21135884e987c4077e2f7184897Vadim BendeburySessionCapGetLoaded(
6945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     TPMI_SH_POLICY      handle,             // IN: start handle
6955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     UINT32              count,              // IN: count of returned handle
6965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     TPML_HANDLE        *handleList          // OUT: list of handle
6975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     )
6985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
6995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     TPMI_YES_NO        more = NO;
7005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     UINT32             i;
7015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     pAssert(HandleGetType(handle) == TPM_HT_LOADED_SESSION);
7025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     // Initialize output handle list
7035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     handleList->count = 0;
7045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     // The maximum count of handles we may return is MAX_CAP_HANDLES
7055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     if(count > MAX_CAP_HANDLES) count = MAX_CAP_HANDLES;
7065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     // Iterate session context ID slots to get loaded session handles
7075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     for(i = handle & HR_HANDLE_MASK; i < MAX_ACTIVE_SESSIONS; i++)
7085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     {
7095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         // If session is active
7105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         if(gr.contextArray[i] != 0)
7115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         {
7125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             // If session is loaded
7135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             if (gr.contextArray[i] <= MAX_LOADED_SESSIONS)
7145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             {
7155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                 if(handleList->count < count)
7165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                 {
7175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                     SESSION         *session;
7185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                        // If we have not filled up the return list, add this
7195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                        // session handle to it
7205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                        // assume that this is going to be an HMAC session
7215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                        handle = i + HMAC_SESSION_FIRST;
7225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                        session = SessionGet(handle);
7235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                        if(session->attributes.isPolicy)
7245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                            handle = i + POLICY_SESSION_FIRST;
7255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                        handleList->handle[handleList->count] = handle;
7265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                        handleList->count++;
7275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                   }
7285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                   else
7295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                   {
7305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                       // If the return list is full but we still have loaded object
7315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                       // available, report this and stop iterating
7325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                       more = YES;
7335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                       break;
7345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                   }
7355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               }
7365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          }
7375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     }
7385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     return more;
7395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
7405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
7415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
7425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//             SessionCapGetSaved()
7435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
7445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function returns a list of handles for saved session, starting at handle.
7455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      Handle must be in a valid handle range, but does not have to point to a saved session
7465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
7475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      Return Value                      Meaning
7485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
7495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      YES                               if there are more handles available
7505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      NO                                all the available handles has been returned
7515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
7525679752bf24c21135884e987c4077e2f7184897Vadim BendeburyTPMI_YES_NO
7535679752bf24c21135884e987c4077e2f7184897Vadim BendeburySessionCapGetSaved(
7545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     TPMI_SH_HMAC        handle,             // IN: start handle
7555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     UINT32              count,              // IN: count of returned handle
7565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     TPML_HANDLE        *handleList          // OUT: list of handle
7575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     )
7585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
7595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     TPMI_YES_NO        more = NO;
7605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     UINT32             i;
7615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   pAssert(HandleGetType(handle) == TPM_HT_ACTIVE_SESSION);
7625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Initialize output handle list
7635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   handleList->count = 0;
7645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // The maximum count of handles we may return is MAX_CAP_HANDLES
7655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(count > MAX_CAP_HANDLES) count = MAX_CAP_HANDLES;
7665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Iterate session context ID slots to get loaded session handles
7675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   for(i = handle & HR_HANDLE_MASK; i < MAX_ACTIVE_SESSIONS; i++)
7685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
7695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // If session is active
7705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       if(gr.contextArray[i] != 0)
7715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       {
7725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           // If session is saved
7735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           if (gr.contextArray[i] > MAX_LOADED_SESSIONS)
7745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           {
7755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               if(handleList->count < count)
7765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               {
7775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                   // If we have not filled up the return list, add this
7785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                   // session handle to it
7795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                   handleList->handle[handleList->count] = i + HMAC_SESSION_FIRST;
7805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                   handleList->count++;
7815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               }
7825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               else
7835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               {
7845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                   // If the return list is full but we still have loaded object
7855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                   // available, report this and stop iterating
7865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                   more = YES;
7875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                   break;
7885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               }
7895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           }
7905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       }
7915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
7925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return more;
7935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
7945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
7955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
7965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//          SessionCapGetLoadedNumber()
7975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
7985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function return the number of authorization sessions currently loaded into TPM RAM.
7995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
8005679752bf24c21135884e987c4077e2f7184897Vadim BendeburyUINT32
8015679752bf24c21135884e987c4077e2f7184897Vadim BendeburySessionCapGetLoadedNumber(
8025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   void
8035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
8045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
8055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return MAX_LOADED_SESSIONS - s_freeSessionSlots;
8065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
8075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
8085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
8095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//          SessionCapGetLoadedAvail()
8105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
8115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function returns the number of additional authorization sessions, of any type, that could be loaded
8125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      into TPM RAM.
8135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
8145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      NOTE:           In other implementations, this number may just be an estimate. The only requirement for the estimate is, if it is
8155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//                      one or more, then at least one session must be loadable.
8165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
8175679752bf24c21135884e987c4077e2f7184897Vadim BendeburyUINT32
8185679752bf24c21135884e987c4077e2f7184897Vadim BendeburySessionCapGetLoadedAvail(
8195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   void
8205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
8215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
8225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     return s_freeSessionSlots;
8235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
8245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
8255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
8265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//           SessionCapGetActiveNumber()
8275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
8285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function returns the number of active authorization sessions currently being tracked by the TPM.
8295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
8305679752bf24c21135884e987c4077e2f7184897Vadim BendeburyUINT32
8315679752bf24c21135884e987c4077e2f7184897Vadim BendeburySessionCapGetActiveNumber(
8325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     void
8335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     )
8345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
8355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     UINT32                  i;
8365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     UINT32                  num = 0;
8375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     // Iterate the context array to find the number of non-zero slots
8385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     for(i = 0; i < MAX_ACTIVE_SESSIONS; i++)
8395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     {
8405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         if(gr.contextArray[i] != 0) num++;
8415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     }
8425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     return num;
8435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
8445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
8455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
8465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//           SessionCapGetActiveAvail()
8475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
8485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function returns the number of additional authorization sessions, of any type, that could be created.
8495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This not the number of slots for sessions, but the number of additional sessions that the TPM is capable
8505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      of tracking.
8515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
8525679752bf24c21135884e987c4077e2f7184897Vadim BendeburyUINT32
8535679752bf24c21135884e987c4077e2f7184897Vadim BendeburySessionCapGetActiveAvail(
8545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     void
8555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     )
8565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
8575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     UINT32                  i;
8585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     UINT32                  num = 0;
8595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     // Iterate the context array to find the number of zero slots
8605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     for(i = 0; i < MAX_ACTIVE_SESSIONS; i++)
8615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     {
8625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         if(gr.contextArray[i] == 0) num++;
8635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     }
8645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     return num;
8655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
866