1 /** @file
2   Implement TPM2 DictionaryAttack related command.
3 
4 Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved. <BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6 
7 **/
8 
9 #include <IndustryStandard/UefiTcgPlatform.h>
10 #include <Library/Tpm2CommandLib.h>
11 #include <Library/Tpm2DeviceLib.h>
12 #include <Library/BaseMemoryLib.h>
13 #include <Library/BaseLib.h>
14 #include <Library/DebugLib.h>
15 
16 #pragma pack(1)
17 
18 typedef struct {
19   TPM2_COMMAND_HEADER       Header;
20   TPMI_RH_LOCKOUT           LockHandle;
21   UINT32                    AuthSessionSize;
22   TPMS_AUTH_COMMAND         AuthSession;
23 } TPM2_DICTIONARY_ATTACK_LOCK_RESET_COMMAND;
24 
25 typedef struct {
26   TPM2_RESPONSE_HEADER       Header;
27   UINT32                     AuthSessionSize;
28   TPMS_AUTH_RESPONSE         AuthSession;
29 } TPM2_DICTIONARY_ATTACK_LOCK_RESET_RESPONSE;
30 
31 typedef struct {
32   TPM2_COMMAND_HEADER       Header;
33   TPMI_RH_LOCKOUT           LockHandle;
34   UINT32                    AuthSessionSize;
35   TPMS_AUTH_COMMAND         AuthSession;
36   UINT32                    NewMaxTries;
37   UINT32                    NewRecoveryTime;
38   UINT32                    LockoutRecovery;
39 } TPM2_DICTIONARY_ATTACK_PARAMETERS_COMMAND;
40 
41 typedef struct {
42   TPM2_RESPONSE_HEADER       Header;
43   UINT32                     AuthSessionSize;
44   TPMS_AUTH_RESPONSE         AuthSession;
45 } TPM2_DICTIONARY_ATTACK_PARAMETERS_RESPONSE;
46 
47 #pragma pack()
48 
49 /**
50   This command cancels the effect of a TPM lockout due to a number of successive authorization failures.
51   If this command is properly authorized, the lockout counter is set to zero.
52 
53   @param[in]  LockHandle            TPM_RH_LOCKOUT
54   @param[in]  AuthSession           Auth Session context
55 
56   @retval EFI_SUCCESS      Operation completed successfully.
57   @retval EFI_DEVICE_ERROR Unexpected device behavior.
58 **/
59 EFI_STATUS
60 EFIAPI
Tpm2DictionaryAttackLockReset(IN TPMI_RH_LOCKOUT LockHandle,IN TPMS_AUTH_COMMAND * AuthSession)61 Tpm2DictionaryAttackLockReset (
62   IN  TPMI_RH_LOCKOUT           LockHandle,
63   IN  TPMS_AUTH_COMMAND         *AuthSession
64   )
65 {
66   EFI_STATUS                                 Status;
67   TPM2_DICTIONARY_ATTACK_LOCK_RESET_COMMAND  SendBuffer;
68   TPM2_DICTIONARY_ATTACK_LOCK_RESET_RESPONSE RecvBuffer;
69   UINT32                                     SendBufferSize;
70   UINT32                                     RecvBufferSize;
71   UINT8                                      *Buffer;
72   UINT32                                     SessionInfoSize;
73 
74   //
75   // Construct command
76   //
77   SendBuffer.Header.tag = SwapBytes16(TPM_ST_SESSIONS);
78   SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_DictionaryAttackLockReset);
79 
80   SendBuffer.LockHandle = SwapBytes32 (LockHandle);
81 
82   //
83   // Add in Auth session
84   //
85   Buffer = (UINT8 *)&SendBuffer.AuthSession;
86 
87   // sessionInfoSize
88   SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
89   Buffer += SessionInfoSize;
90   SendBuffer.AuthSessionSize = SwapBytes32(SessionInfoSize);
91 
92   SendBufferSize = (UINT32)((UINTN)Buffer - (UINTN)&SendBuffer);
93   SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);
94 
95   //
96   // send Tpm command
97   //
98   RecvBufferSize = sizeof (RecvBuffer);
99   Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);
100   if (EFI_ERROR (Status)) {
101     goto Done;
102   }
103 
104   if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {
105     DEBUG ((EFI_D_ERROR, "Tpm2DictionaryAttackLockReset - RecvBufferSize Error - %x\n", RecvBufferSize));
106     Status = EFI_DEVICE_ERROR;
107     goto Done;
108   }
109   if (SwapBytes32(RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) {
110     DEBUG ((EFI_D_ERROR, "Tpm2DictionaryAttackLockReset - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));
111     Status = EFI_DEVICE_ERROR;
112     goto Done;
113   }
114 
115 Done:
116   //
117   // Clear AuthSession Content
118   //
119   ZeroMem (&SendBuffer, sizeof(SendBuffer));
120   ZeroMem (&RecvBuffer, sizeof(RecvBuffer));
121   return Status;
122 }
123 
124 /**
125   This command cancels the effect of a TPM lockout due to a number of successive authorization failures.
126   If this command is properly authorized, the lockout counter is set to zero.
127 
128   @param[in]  LockHandle            TPM_RH_LOCKOUT
129   @param[in]  AuthSession           Auth Session context
130   @param[in]  NewMaxTries           Count of authorization failures before the lockout is imposed
131   @param[in]  NewRecoveryTime       Time in seconds before the authorization failure count is automatically decremented
132   @param[in]  LockoutRecovery       Time in seconds after a lockoutAuth failure before use of lockoutAuth is allowed
133 
134   @retval EFI_SUCCESS      Operation completed successfully.
135   @retval EFI_DEVICE_ERROR Unexpected device behavior.
136 **/
137 EFI_STATUS
138 EFIAPI
Tpm2DictionaryAttackParameters(IN TPMI_RH_LOCKOUT LockHandle,IN TPMS_AUTH_COMMAND * AuthSession,IN UINT32 NewMaxTries,IN UINT32 NewRecoveryTime,IN UINT32 LockoutRecovery)139 Tpm2DictionaryAttackParameters (
140   IN  TPMI_RH_LOCKOUT           LockHandle,
141   IN  TPMS_AUTH_COMMAND         *AuthSession,
142   IN  UINT32                    NewMaxTries,
143   IN  UINT32                    NewRecoveryTime,
144   IN  UINT32                    LockoutRecovery
145   )
146 {
147   EFI_STATUS                                 Status;
148   TPM2_DICTIONARY_ATTACK_PARAMETERS_COMMAND  SendBuffer;
149   TPM2_DICTIONARY_ATTACK_PARAMETERS_RESPONSE RecvBuffer;
150   UINT32                                     SendBufferSize;
151   UINT32                                     RecvBufferSize;
152   UINT8                                      *Buffer;
153   UINT32                                     SessionInfoSize;
154 
155   //
156   // Construct command
157   //
158   SendBuffer.Header.tag = SwapBytes16(TPM_ST_SESSIONS);
159   SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_DictionaryAttackParameters);
160 
161   SendBuffer.LockHandle = SwapBytes32 (LockHandle);
162 
163   //
164   // Add in Auth session
165   //
166   Buffer = (UINT8 *)&SendBuffer.AuthSession;
167 
168   // sessionInfoSize
169   SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
170   Buffer += SessionInfoSize;
171   SendBuffer.AuthSessionSize = SwapBytes32(SessionInfoSize);
172 
173   //
174   // Real data
175   //
176   WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32(NewMaxTries));
177   Buffer += sizeof(UINT32);
178   WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32(NewRecoveryTime));
179   Buffer += sizeof(UINT32);
180   WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32(LockoutRecovery));
181   Buffer += sizeof(UINT32);
182 
183   SendBufferSize = (UINT32)((UINTN)Buffer - (UINTN)&SendBuffer);
184   SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);
185 
186   //
187   // send Tpm command
188   //
189   RecvBufferSize = sizeof (RecvBuffer);
190   Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);
191   if (EFI_ERROR (Status)) {
192     goto Done;
193   }
194 
195   if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {
196     DEBUG ((EFI_D_ERROR, "Tpm2DictionaryAttackParameters - RecvBufferSize Error - %x\n", RecvBufferSize));
197     Status = EFI_DEVICE_ERROR;
198     goto Done;
199   }
200   if (SwapBytes32(RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) {
201     DEBUG ((EFI_D_ERROR, "Tpm2DictionaryAttackParameters - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));
202     Status = EFI_DEVICE_ERROR;
203     goto Done;
204   }
205 
206 Done:
207   //
208   // Clear AuthSession Content
209   //
210   ZeroMem (&SendBufferSize, sizeof(SendBufferSize));
211   ZeroMem (&RecvBuffer, sizeof(RecvBuffer));
212   return Status;
213 }
214