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      // TODO(vbendeb): consider finer tuning of this value (crosbug.com/p/55708)
     28      gp.maxTries = 200;
     29      gp.recoveryTime = 1000;                  // in seconds (~16.67 minutes)
     30      gp.lockoutRecovery = 1000;               // in seconds
     31      gp.lockOutAuthEnabled = TRUE;            // Use of lockoutAuth is enabled
     32      // Record persistent DA parameter changes to NV
     33      NvWriteReserved(NV_FAILED_TRIES, &gp.failedTries);
     34      NvWriteReserved(NV_MAX_TRIES, &gp.maxTries);
     35      NvWriteReserved(NV_RECOVERY_TIME, &gp.recoveryTime);
     36      NvWriteReserved(NV_LOCKOUT_RECOVERY, &gp.lockoutRecovery);
     37      NvWriteReserved(NV_LOCKOUT_AUTH_ENABLED, &gp.lockOutAuthEnabled);
     38     return;
     39 }
     40 //
     41 //
     42 //          DAStartup()
     43 //
     44 //     This function is called by TPM2_Startup() to initialize the DA parameters. In the case of Startup(CLEAR),
     45 //     use of lockoutAuth will be enabled if the lockout recovery time is 0. Otherwise, lockoutAuth will not be
     46 //     enabled until the TPM has been continuously powered for the lockoutRecovery time.
     47 //     This function requires that NV be available and not rate limiting.
     48 //
     49 void
     50 DAStartup(
     51     STARTUP_TYPE         type               // IN: startup type
     52     )
     53 {
     54     // For TPM Reset, if lockoutRecovery is 0, enable use of lockoutAuth.
     55     if(type == SU_RESET)
     56     {
     57         if(gp.lockoutRecovery == 0)
     58         {
     59             gp.lockOutAuthEnabled = TRUE;
     60             // Record the changes to NV
     61             NvWriteReserved(NV_LOCKOUT_AUTH_ENABLED, &gp.lockOutAuthEnabled);
     62         }
     63     }
     64     // If DA has not been disabled and the previous shutdown is not orderly
     65     // failedTries is not already at its maximum then increment 'failedTries'
     66     if(    gp.recoveryTime != 0
     67         && g_prevOrderlyState == SHUTDOWN_NONE
     68         && gp.failedTries < gp.maxTries)
     69     {
     70         gp.failedTries++;
     71         // Record the change to NV
     72         NvWriteReserved(NV_FAILED_TRIES, &gp.failedTries);
     73     }
     74     // Reset self healing timers
     75     s_selfHealTimer = g_time;
     76     s_lockoutTimer = g_time;
     77     return;
     78 }
     79 //
     80 //
     81 //          DARegisterFailure()
     82 //
     83 //     This function is called when a authorization failure occurs on an entity that is subject to dictionary-attack
     84 //     protection. When a DA failure is triggered, register the failure by resetting the relevant self-healing timer
     85 //     to the current time.
     86 //
     87 void
     88 DARegisterFailure(
     89     TPM_HANDLE           handle             // IN: handle for failure
     90     )
     91 {
     92     // Reset the timer associated with lockout if the handle is the lockout auth.
     93     if(handle == TPM_RH_LOCKOUT)
     94          s_lockoutTimer = g_time;
     95     else
     96          s_selfHealTimer = g_time;
     97 //
     98    return;
     99 }
    100 //
    101 //
    102 //             DASelfHeal()
    103 //
    104 //      This function is called to check if sufficient time has passed to allow decrement of failedTries or to re-
    105 //      enable use of lockoutAuth.
    106 //      This function should be called when the time interval is updated.
    107 //
    108 void
    109 DASelfHeal(
    110    void
    111    )
    112 {
    113    // Regular auth self healing logic
    114    // If no failed authorization tries, do nothing. Otherwise, try to
    115    // decrease failedTries
    116    if(gp.failedTries != 0)
    117    {
    118        // if recovery time is 0, DA logic has been disabled. Clear failed tries
    119        // immediately
    120        if(gp.recoveryTime == 0)
    121        {
    122             gp.failedTries = 0;
    123             // Update NV record
    124             NvWriteReserved(NV_FAILED_TRIES, &gp.failedTries);
    125        }
    126        else
    127        {
    128             UINT64          decreaseCount;
    129                // In the unlikely event that failedTries should become larger than
    130                // maxTries
    131                if(gp.failedTries > gp.maxTries)
    132                    gp.failedTries = gp.maxTries;
    133                // How much can failedTried be decreased
    134                decreaseCount = ((g_time - s_selfHealTimer) / 1000) / gp.recoveryTime;
    135                if(gp.failedTries <= (UINT32) decreaseCount)
    136                    // should not set failedTries below zero
    137                    gp.failedTries = 0;
    138                else
    139                    gp.failedTries -= (UINT32) decreaseCount;
    140                // the cast prevents overflow of the product
    141                s_selfHealTimer += (decreaseCount * (UINT64)gp.recoveryTime) * 1000;
    142                if(decreaseCount != 0)
    143                    // If there was a change to the failedTries, record the changes
    144                    // to NV
    145                    NvWriteReserved(NV_FAILED_TRIES, &gp.failedTries);
    146          }
    147    }
    148    // LockoutAuth self healing logic
    149    // If lockoutAuth is enabled, do nothing. Otherwise, try to see if we
    150    // may enable it
    151    if(!gp.lockOutAuthEnabled)
    152    {
    153        // if lockout authorization recovery time is 0, a reboot is required to
    154        // re-enable use of lockout authorization. Self-healing would not
    155        // apply in this case.
    156        if(gp.lockoutRecovery != 0)
    157 //
    158            {
    159                  if(((g_time - s_lockoutTimer)/1000) >= gp.lockoutRecovery)
    160                  {
    161                      gp.lockOutAuthEnabled = TRUE;
    162                      // Record the changes to NV
    163                      NvWriteReserved(NV_LOCKOUT_AUTH_ENABLED, &gp.lockOutAuthEnabled);
    164                  }
    165            }
    166      }
    167      return;
    168 }
    169