Home | History | Annotate | Download | only in tpm2
      1 // This file was extracted from the TCG Published
      2 // Trusted Platform Module Library
      3 // Part 4: Supporting Routines
      4 // Family "2.0"
      5 // Level 00 Revision 01.16
      6 // October 30, 2014
      7 
      8 #define DA_C
      9 #include "InternalRoutines.h"
     10 //
     11 //
     12 //           Functions
     13 //
     14 //            DAPreInstall_Init()
     15 //
     16 //      This function initializes the DA parameters to their manufacturer-default values. The default values are
     17 //      determined by a platform-specific specification.
     18 //      This function should not be called outside of a manufacturing or simulation environment.
     19 //      The DA parameters will be restored to these initial values by TPM2_Clear().
     20 //
     21 void
     22 DAPreInstall_Init(
     23      void
     24      )
     25 {
     26      gp.failedTries = 0;
     27      gp.maxTries = 3;
     28      gp.recoveryTime = 1000;                  // in seconds (~16.67 minutes)
     29      gp.lockoutRecovery = 1000;               // in seconds
     30      gp.lockOutAuthEnabled = TRUE;            // Use of lockoutAuth is enabled
     31      // Record persistent DA parameter changes to NV
     32      NvWriteReserved(NV_FAILED_TRIES, &gp.failedTries);
     33      NvWriteReserved(NV_MAX_TRIES, &gp.maxTries);
     34      NvWriteReserved(NV_RECOVERY_TIME, &gp.recoveryTime);
     35      NvWriteReserved(NV_LOCKOUT_RECOVERY, &gp.lockoutRecovery);
     36      NvWriteReserved(NV_LOCKOUT_AUTH_ENABLED, &gp.lockOutAuthEnabled);
     37     return;
     38 }
     39 //
     40 //
     41 //          DAStartup()
     42 //
     43 //     This function is called by TPM2_Startup() to initialize the DA parameters. In the case of Startup(CLEAR),
     44 //     use of lockoutAuth will be enabled if the lockout recovery time is 0. Otherwise, lockoutAuth will not be
     45 //     enabled until the TPM has been continuously powered for the lockoutRecovery time.
     46 //     This function requires that NV be available and not rate limiting.
     47 //
     48 void
     49 DAStartup(
     50     STARTUP_TYPE         type               // IN: startup type
     51     )
     52 {
     53     // For TPM Reset, if lockoutRecovery is 0, enable use of lockoutAuth.
     54     if(type == SU_RESET)
     55     {
     56         if(gp.lockoutRecovery == 0)
     57         {
     58             gp.lockOutAuthEnabled = TRUE;
     59             // Record the changes to NV
     60             NvWriteReserved(NV_LOCKOUT_AUTH_ENABLED, &gp.lockOutAuthEnabled);
     61         }
     62     }
     63     // If DA has not been disabled and the previous shutdown is not orderly
     64     // failedTries is not already at its maximum then increment 'failedTries'
     65     if(    gp.recoveryTime != 0
     66         && g_prevOrderlyState == SHUTDOWN_NONE
     67         && gp.failedTries < gp.maxTries)
     68     {
     69         gp.failedTries++;
     70         // Record the change to NV
     71         NvWriteReserved(NV_FAILED_TRIES, &gp.failedTries);
     72     }
     73     // Reset self healing timers
     74     s_selfHealTimer = g_time;
     75     s_lockoutTimer = g_time;
     76     return;
     77 }
     78 //
     79 //
     80 //          DARegisterFailure()
     81 //
     82 //     This function is called when a authorization failure occurs on an entity that is subject to dictionary-attack
     83 //     protection. When a DA failure is triggered, register the failure by resetting the relevant self-healing timer
     84 //     to the current time.
     85 //
     86 void
     87 DARegisterFailure(
     88     TPM_HANDLE           handle             // IN: handle for failure
     89     )
     90 {
     91     // Reset the timer associated with lockout if the handle is the lockout auth.
     92     if(handle == TPM_RH_LOCKOUT)
     93          s_lockoutTimer = g_time;
     94     else
     95          s_selfHealTimer = g_time;
     96 //
     97    return;
     98 }
     99 //
    100 //
    101 //             DASelfHeal()
    102 //
    103 //      This function is called to check if sufficient time has passed to allow decrement of failedTries or to re-
    104 //      enable use of lockoutAuth.
    105 //      This function should be called when the time interval is updated.
    106 //
    107 void
    108 DASelfHeal(
    109    void
    110    )
    111 {
    112    // Regular auth self healing logic
    113    // If no failed authorization tries, do nothing. Otherwise, try to
    114    // decrease failedTries
    115    if(gp.failedTries != 0)
    116    {
    117        // if recovery time is 0, DA logic has been disabled. Clear failed tries
    118        // immediately
    119        if(gp.recoveryTime == 0)
    120        {
    121             gp.failedTries = 0;
    122             // Update NV record
    123             NvWriteReserved(NV_FAILED_TRIES, &gp.failedTries);
    124        }
    125        else
    126        {
    127             UINT64          decreaseCount;
    128                // In the unlikely event that failedTries should become larger than
    129                // maxTries
    130                if(gp.failedTries > gp.maxTries)
    131                    gp.failedTries = gp.maxTries;
    132                // How much can failedTried be decreased
    133                decreaseCount = ((g_time - s_selfHealTimer) / 1000) / gp.recoveryTime;
    134                if(gp.failedTries <= (UINT32) decreaseCount)
    135                    // should not set failedTries below zero
    136                    gp.failedTries = 0;
    137                else
    138                    gp.failedTries -= (UINT32) decreaseCount;
    139                // the cast prevents overflow of the product
    140                s_selfHealTimer += (decreaseCount * (UINT64)gp.recoveryTime) * 1000;
    141                if(decreaseCount != 0)
    142                    // If there was a change to the failedTries, record the changes
    143                    // to NV
    144                    NvWriteReserved(NV_FAILED_TRIES, &gp.failedTries);
    145          }
    146    }
    147    // LockoutAuth self healing logic
    148    // If lockoutAuth is enabled, do nothing. Otherwise, try to see if we
    149    // may enable it
    150    if(!gp.lockOutAuthEnabled)
    151    {
    152        // if lockout authorization recovery time is 0, a reboot is required to
    153        // re-enable use of lockout authorization. Self-healing would not
    154        // apply in this case.
    155        if(gp.lockoutRecovery != 0)
    156 //
    157            {
    158                  if(((g_time - s_lockoutTimer)/1000) >= gp.lockoutRecovery)
    159                  {
    160                      gp.lockOutAuthEnabled = TRUE;
    161                      // Record the changes to NV
    162                      NvWriteReserved(NV_LOCKOUT_AUTH_ENABLED, &gp.lockOutAuthEnabled);
    163                  }
    164            }
    165      }
    166      return;
    167 }
    168