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