diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 21:41:43 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 21:41:43 +0000 |
commit | 92cccad89d1c12b39165d5f0ed7ccd2d44965a1a (patch) | |
tree | f59a2764cd8c50959050a428bd8fc935138df750 /src/tpm2/DA.c | |
parent | Initial commit. (diff) | |
download | libtpms-upstream/0.9.2.tar.xz libtpms-upstream/0.9.2.zip |
Adding upstream version 0.9.2.upstream/0.9.2upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/tpm2/DA.c')
-rw-r--r-- | src/tpm2/DA.c | 240 |
1 files changed, 240 insertions, 0 deletions
diff --git a/src/tpm2/DA.c b/src/tpm2/DA.c new file mode 100644 index 0000000..d61272e --- /dev/null +++ b/src/tpm2/DA.c @@ -0,0 +1,240 @@ +/********************************************************************************/ +/* */ +/* Dictionary Attack Logic. */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: DA.c 1658 2021-01-22 23:14:01Z kgoldman $ */ +/* */ +/* Licenses and Notices */ +/* */ +/* 1. Copyright Licenses: */ +/* */ +/* - Trusted Computing Group (TCG) grants to the user of the source code in */ +/* this specification (the "Source Code") a worldwide, irrevocable, */ +/* nonexclusive, royalty free, copyright license to reproduce, create */ +/* derivative works, distribute, display and perform the Source Code and */ +/* derivative works thereof, and to grant others the rights granted herein. */ +/* */ +/* - The TCG grants to the user of the other parts of the specification */ +/* (other than the Source Code) the rights to reproduce, distribute, */ +/* display, and perform the specification solely for the purpose of */ +/* developing products based on such documents. */ +/* */ +/* 2. Source Code Distribution Conditions: */ +/* */ +/* - Redistributions of Source Code must retain the above copyright licenses, */ +/* this list of conditions and the following disclaimers. */ +/* */ +/* - Redistributions in binary form must reproduce the above copyright */ +/* licenses, this list of conditions and the following disclaimers in the */ +/* documentation and/or other materials provided with the distribution. */ +/* */ +/* 3. Disclaimers: */ +/* */ +/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */ +/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */ +/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */ +/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */ +/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */ +/* information on specification licensing rights available through TCG */ +/* membership agreements. */ +/* */ +/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */ +/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */ +/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */ +/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */ +/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */ +/* */ +/* - Without limitation, TCG and its members and licensors disclaim all */ +/* liability, including liability for infringement of any proprietary */ +/* rights, relating to use of information in this specification and to the */ +/* implementation of this specification, and TCG disclaims all liability for */ +/* cost of procurement of substitute goods or services, lost profits, loss */ +/* of use, loss of data or any incidental, consequential, direct, indirect, */ +/* or special damages, whether under contract, tort, warranty or otherwise, */ +/* arising in any way out of use or reliance upon this specification or any */ +/* information herein. */ +/* */ +/* (c) Copyright IBM Corp. and others, 2016 - 2019 */ +/* */ +/********************************************************************************/ + +/* 8.2 DA.c */ +/* 8.2.1 Introduction */ +/* This file contains the functions and data definitions relating to the dictionary attack logic. */ +/* 8.2.2 Includes and Data Definitions */ +#define DA_C +#include "Tpm.h" +/* 8.2.3 Functions */ +/* 8.2.3.1 DAPreInstall_Init() */ +/* This function initializes the DA parameters to their manufacturer-default values. The default + values are determined by a platform-specific specification. */ +/* This function should not be called outside of a manufacturing or simulation environment. */ +/* The DA parameters will be restored to these initial values by TPM2_Clear(). */ +void +DAPreInstall_Init( + void + ) +{ + gp.failedTries = 0; + gp.maxTries = 3; + gp.recoveryTime = 1000; // in seconds (~16.67 minutes) + gp.lockoutRecovery = 1000; // in seconds + gp.lockOutAuthEnabled = TRUE; // Use of lockoutAuth is enabled + // Record persistent DA parameter changes to NV + NV_SYNC_PERSISTENT(failedTries); + NV_SYNC_PERSISTENT(maxTries); + NV_SYNC_PERSISTENT(recoveryTime); + NV_SYNC_PERSISTENT(lockoutRecovery); + NV_SYNC_PERSISTENT(lockOutAuthEnabled); + return; +} +/* 8.2.3.2 DAStartup() */ +/* This function is called by TPM2_Startup() to initialize the DA parameters. In the case of + Startup(CLEAR), use of lockoutAuth will be enabled if the lockout recovery time is 0. Otherwise, + lockoutAuth will not be enabled until the TPM has been continuously powered for the + lockoutRecovery time. */ +/* This function requires that NV be available and not rate limiting. */ +BOOL +DAStartup( + STARTUP_TYPE type // IN: startup type + ) +{ + NOT_REFERENCED(type); +#if !ACCUMULATE_SELF_HEAL_TIMER + _plat__TimerWasReset(); + s_selfHealTimer = 0; + s_lockoutTimer = 0; +#else + if(_plat__TimerWasReset()) + { + if(!NV_IS_ORDERLY) + { + // If shutdown was not orderly, then don't really know if go.time has + // any useful value so reset the timer to 0. This is what the tick + // was reset to + s_selfHealTimer = 0; + s_lockoutTimer = 0; + } + else + { + // If we know how much time was accumulated at the last orderly shutdown + // subtract that from the saved timer values so that they effectively + // have the accumulated values + s_selfHealTimer -= go.time; + s_lockoutTimer -= go.time; + } + } +#endif + // For any Startup(), if lockoutRecovery is 0, enable use of lockoutAuth. + if(gp.lockoutRecovery == 0) + { + gp.lockOutAuthEnabled = TRUE; + // Record the changes to NV + NV_SYNC_PERSISTENT(lockOutAuthEnabled); + } + // If DA has not been disabled and the previous shutdown is not orderly + // failedTries is not already at its maximum then increment 'failedTries' + if(gp.recoveryTime != 0 + && gp.failedTries < gp.maxTries + && !IS_ORDERLY(g_prevOrderlyState)) + { +#if USE_DA_USED + gp.failedTries += g_daUsed; + g_daUsed = FALSE; +#else + gp.failedTries++; +#endif + // Record the change to NV + NV_SYNC_PERSISTENT(failedTries); + } + // Before Startup, the TPM will not do clock updates. At startup, need to + // do a time update which will do the DA update. + TimeUpdate(); + return TRUE; +} +/* 8.2.3.3 DARegisterFailure() */ +/* This function is called when an authorization failure occurs on an entity that is subject to + dictionary-attack protection. When a DA failure is triggered, register the failure by resetting + the relevant self-healing timer to the current time. */ +void +DARegisterFailure( + TPM_HANDLE handle // IN: handle for failure + ) +{ + // Reset the timer associated with lockout if the handle is the lockoutAuth. + if(handle == TPM_RH_LOCKOUT) + s_lockoutTimer = g_time; + else + s_selfHealTimer = g_time; + return; +} +/* 8.2.3.4 DASelfHeal() */ +/* This function is called to check if sufficient time has passed to allow decrement of failedTries + or to re-enable use of lockoutAuth. */ +/* This function should be called when the time interval is updated. */ +void +DASelfHeal( + void + ) +{ + // Regular authorization self healing logic + // If no failed authorization tries, do nothing. Otherwise, try to + // decrease failedTries + if(gp.failedTries != 0) + { + // if recovery time is 0, DA logic has been disabled. Clear failed tries + // immediately + if(gp.recoveryTime == 0) + { + gp.failedTries = 0; + // Update NV record + NV_SYNC_PERSISTENT(failedTries); + } + else + { + UINT64 decreaseCount; +#if 0 // Errata eliminates this code + // In the unlikely event that failedTries should become larger than + // maxTries + if(gp.failedTries > gp.maxTries) + gp.failedTries = gp.maxTries; +#endif + // How much can failedTries be decreased + // Cast s_selfHealTimer to an int in case it became negative at + // startup + decreaseCount = ((g_time - (INT64)s_selfHealTimer) / 1000) + / gp.recoveryTime; + if(gp.failedTries <= (UINT32)decreaseCount) + // should not set failedTries below zero + gp.failedTries = 0; + else + gp.failedTries -= (UINT32)decreaseCount; + // the cast prevents overflow of the product + s_selfHealTimer += (decreaseCount * (UINT64)gp.recoveryTime) * 1000; + if(decreaseCount != 0) + // If there was a change to the failedTries, record the changes + // to NV + NV_SYNC_PERSISTENT(failedTries); + } + } + // LockoutAuth self healing logic + // If lockoutAuth is enabled, do nothing. Otherwise, try to see if we + // may enable it + if(!gp.lockOutAuthEnabled) + { + // if lockout authorization recovery time is 0, a reboot is required to + // re-enable use of lockout authorization. Self-healing would not + // apply in this case. + if(gp.lockoutRecovery != 0) + { + if(((g_time - (INT64)s_lockoutTimer) / 1000) >= gp.lockoutRecovery) + { + gp.lockOutAuthEnabled = TRUE; + // Record the changes to NV + NV_SYNC_PERSISTENT(lockOutAuthEnabled); + } + } + } + return; +} |