1 /** @file
2   Implement TPM2 NVStorage related command.
3 
4 Copyright (c) 2013 - 2018, 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 #define RC_NV_ReadPublic_nvIndex            (TPM_RC_H + TPM_RC_1)
19 
20 #define RC_NV_DefineSpace_authHandle        (TPM_RC_H + TPM_RC_1)
21 #define RC_NV_DefineSpace_auth              (TPM_RC_P + TPM_RC_1)
22 #define RC_NV_DefineSpace_publicInfo        (TPM_RC_P + TPM_RC_2)
23 
24 #define RC_NV_UndefineSpace_authHandle      (TPM_RC_H + TPM_RC_1)
25 #define RC_NV_UndefineSpace_nvIndex         (TPM_RC_H + TPM_RC_2)
26 
27 #define RC_NV_Read_authHandle               (TPM_RC_H + TPM_RC_1)
28 #define RC_NV_Read_nvIndex                  (TPM_RC_H + TPM_RC_2)
29 #define RC_NV_Read_size                     (TPM_RC_P + TPM_RC_1)
30 #define RC_NV_Read_offset                   (TPM_RC_P + TPM_RC_2)
31 
32 #define RC_NV_Write_authHandle              (TPM_RC_H + TPM_RC_1)
33 #define RC_NV_Write_nvIndex                 (TPM_RC_H + TPM_RC_2)
34 #define RC_NV_Write_data                    (TPM_RC_P + TPM_RC_1)
35 #define RC_NV_Write_offset                  (TPM_RC_P + TPM_RC_2)
36 
37 typedef struct {
38   TPM2_COMMAND_HEADER       Header;
39   TPMI_RH_NV_INDEX          NvIndex;
40 } TPM2_NV_READPUBLIC_COMMAND;
41 
42 typedef struct {
43   TPM2_RESPONSE_HEADER      Header;
44   TPM2B_NV_PUBLIC           NvPublic;
45   TPM2B_NAME                NvName;
46 } TPM2_NV_READPUBLIC_RESPONSE;
47 
48 typedef struct {
49   TPM2_COMMAND_HEADER       Header;
50   TPMI_RH_PROVISION         AuthHandle;
51   UINT32                    AuthSessionSize;
52   TPMS_AUTH_COMMAND         AuthSession;
53   TPM2B_AUTH                Auth;
54   TPM2B_NV_PUBLIC           NvPublic;
55 } TPM2_NV_DEFINESPACE_COMMAND;
56 
57 typedef struct {
58   TPM2_RESPONSE_HEADER       Header;
59   UINT32                     AuthSessionSize;
60   TPMS_AUTH_RESPONSE         AuthSession;
61 } TPM2_NV_DEFINESPACE_RESPONSE;
62 
63 typedef struct {
64   TPM2_COMMAND_HEADER       Header;
65   TPMI_RH_PROVISION         AuthHandle;
66   TPMI_RH_NV_INDEX          NvIndex;
67   UINT32                    AuthSessionSize;
68   TPMS_AUTH_COMMAND         AuthSession;
69 } TPM2_NV_UNDEFINESPACE_COMMAND;
70 
71 typedef struct {
72   TPM2_RESPONSE_HEADER       Header;
73   UINT32                     AuthSessionSize;
74   TPMS_AUTH_RESPONSE         AuthSession;
75 } TPM2_NV_UNDEFINESPACE_RESPONSE;
76 
77 typedef struct {
78   TPM2_COMMAND_HEADER       Header;
79   TPMI_RH_NV_AUTH           AuthHandle;
80   TPMI_RH_NV_INDEX          NvIndex;
81   UINT32                    AuthSessionSize;
82   TPMS_AUTH_COMMAND         AuthSession;
83   UINT16                    Size;
84   UINT16                    Offset;
85 } TPM2_NV_READ_COMMAND;
86 
87 typedef struct {
88   TPM2_RESPONSE_HEADER       Header;
89   UINT32                     AuthSessionSize;
90   TPM2B_MAX_BUFFER           Data;
91   TPMS_AUTH_RESPONSE         AuthSession;
92 } TPM2_NV_READ_RESPONSE;
93 
94 typedef struct {
95   TPM2_COMMAND_HEADER       Header;
96   TPMI_RH_NV_AUTH           AuthHandle;
97   TPMI_RH_NV_INDEX          NvIndex;
98   UINT32                    AuthSessionSize;
99   TPMS_AUTH_COMMAND         AuthSession;
100   TPM2B_MAX_BUFFER          Data;
101   UINT16                    Offset;
102 } TPM2_NV_WRITE_COMMAND;
103 
104 typedef struct {
105   TPM2_RESPONSE_HEADER       Header;
106   UINT32                     AuthSessionSize;
107   TPMS_AUTH_RESPONSE         AuthSession;
108 } TPM2_NV_WRITE_RESPONSE;
109 
110 typedef struct {
111   TPM2_COMMAND_HEADER       Header;
112   TPMI_RH_NV_AUTH           AuthHandle;
113   TPMI_RH_NV_INDEX          NvIndex;
114   UINT32                    AuthSessionSize;
115   TPMS_AUTH_COMMAND         AuthSession;
116 } TPM2_NV_READLOCK_COMMAND;
117 
118 typedef struct {
119   TPM2_RESPONSE_HEADER       Header;
120   UINT32                     AuthSessionSize;
121   TPMS_AUTH_RESPONSE         AuthSession;
122 } TPM2_NV_READLOCK_RESPONSE;
123 
124 typedef struct {
125   TPM2_COMMAND_HEADER       Header;
126   TPMI_RH_NV_AUTH           AuthHandle;
127   TPMI_RH_NV_INDEX          NvIndex;
128   UINT32                    AuthSessionSize;
129   TPMS_AUTH_COMMAND         AuthSession;
130 } TPM2_NV_WRITELOCK_COMMAND;
131 
132 typedef struct {
133   TPM2_RESPONSE_HEADER       Header;
134   UINT32                     AuthSessionSize;
135   TPMS_AUTH_RESPONSE         AuthSession;
136 } TPM2_NV_WRITELOCK_RESPONSE;
137 
138 typedef struct {
139   TPM2_COMMAND_HEADER       Header;
140   TPMI_RH_PROVISION         AuthHandle;
141   UINT32                    AuthSessionSize;
142   TPMS_AUTH_COMMAND         AuthSession;
143 } TPM2_NV_GLOBALWRITELOCK_COMMAND;
144 
145 typedef struct {
146   TPM2_RESPONSE_HEADER       Header;
147   UINT32                     AuthSessionSize;
148   TPMS_AUTH_RESPONSE         AuthSession;
149 } TPM2_NV_GLOBALWRITELOCK_RESPONSE;
150 
151 #pragma pack()
152 
153 /**
154   This command is used to read the public area and Name of an NV Index.
155 
156   @param[in]  NvIndex            The NV Index.
157   @param[out] NvPublic           The public area of the index.
158   @param[out] NvName             The Name of the nvIndex.
159 
160   @retval EFI_SUCCESS            Operation completed successfully.
161   @retval EFI_DEVICE_ERROR       The command was unsuccessful.
162   @retval EFI_NOT_FOUND          The command was returned successfully, but NvIndex is not found.
163 **/
164 EFI_STATUS
165 EFIAPI
Tpm2NvReadPublic(IN TPMI_RH_NV_INDEX NvIndex,OUT TPM2B_NV_PUBLIC * NvPublic,OUT TPM2B_NAME * NvName)166 Tpm2NvReadPublic (
167   IN      TPMI_RH_NV_INDEX          NvIndex,
168   OUT     TPM2B_NV_PUBLIC           *NvPublic,
169   OUT     TPM2B_NAME                *NvName
170   )
171 {
172   EFI_STATUS                        Status;
173   TPM2_NV_READPUBLIC_COMMAND        SendBuffer;
174   TPM2_NV_READPUBLIC_RESPONSE       RecvBuffer;
175   UINT32                            SendBufferSize;
176   UINT32                            RecvBufferSize;
177   UINT16                            NvPublicSize;
178   UINT16                            NvNameSize;
179   UINT8                             *Buffer;
180   TPM_RC                            ResponseCode;
181 
182   //
183   // Construct command
184   //
185   SendBuffer.Header.tag = SwapBytes16(TPM_ST_NO_SESSIONS);
186   SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_NV_ReadPublic);
187 
188   SendBuffer.NvIndex = SwapBytes32 (NvIndex);
189 
190   SendBufferSize = (UINT32) sizeof (SendBuffer);
191   SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);
192 
193   //
194   // send Tpm command
195   //
196   RecvBufferSize = sizeof (RecvBuffer);
197   Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);
198   if (EFI_ERROR (Status)) {
199     return Status;
200   }
201 
202   if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {
203     DEBUG ((EFI_D_ERROR, "Tpm2NvReadPublic - RecvBufferSize Error - %x\n", RecvBufferSize));
204     return EFI_DEVICE_ERROR;
205   }
206   ResponseCode = SwapBytes32(RecvBuffer.Header.responseCode);
207   if (ResponseCode != TPM_RC_SUCCESS) {
208     DEBUG ((EFI_D_ERROR, "Tpm2NvReadPublic - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));
209   }
210   switch (ResponseCode) {
211   case TPM_RC_SUCCESS:
212     // return data
213     break;
214   case TPM_RC_HANDLE + RC_NV_ReadPublic_nvIndex: // TPM_RC_NV_DEFINED:
215     return EFI_NOT_FOUND;
216   case TPM_RC_VALUE + RC_NV_ReadPublic_nvIndex:
217     return EFI_INVALID_PARAMETER;
218   default:
219     return EFI_DEVICE_ERROR;
220   }
221 
222   if (RecvBufferSize <= sizeof (TPM2_RESPONSE_HEADER) + sizeof (UINT16) + sizeof(UINT16)) {
223     DEBUG ((EFI_D_ERROR, "Tpm2NvReadPublic - RecvBufferSize Error - %x\n", RecvBufferSize));
224     return EFI_NOT_FOUND;
225   }
226 
227   //
228   // Basic check
229   //
230   NvPublicSize = SwapBytes16 (RecvBuffer.NvPublic.size);
231   if (NvPublicSize > sizeof(TPMS_NV_PUBLIC)) {
232     DEBUG ((DEBUG_ERROR, "Tpm2NvReadPublic - NvPublic.size error %x\n", NvPublicSize));
233     return EFI_DEVICE_ERROR;
234   }
235 
236   NvNameSize = SwapBytes16 (ReadUnaligned16 ((UINT16 *)((UINT8 *)&RecvBuffer + sizeof(TPM2_RESPONSE_HEADER) + sizeof(UINT16) + NvPublicSize)));
237   if (NvNameSize > sizeof(TPMU_NAME)){
238     DEBUG ((DEBUG_ERROR, "Tpm2NvReadPublic - NvNameSize error %x\n", NvNameSize));
239     return EFI_DEVICE_ERROR;
240   }
241 
242   if (RecvBufferSize != sizeof(TPM2_RESPONSE_HEADER) + sizeof(UINT16) + NvPublicSize + sizeof(UINT16) + NvNameSize) {
243     DEBUG ((EFI_D_ERROR, "Tpm2NvReadPublic - RecvBufferSize Error - NvPublicSize %x\n", RecvBufferSize));
244     return EFI_NOT_FOUND;
245   }
246 
247   //
248   // Return the response
249   //
250   CopyMem (NvPublic, &RecvBuffer.NvPublic, sizeof(UINT16) + NvPublicSize);
251   NvPublic->size = NvPublicSize;
252   NvPublic->nvPublic.nvIndex = SwapBytes32 (NvPublic->nvPublic.nvIndex);
253   NvPublic->nvPublic.nameAlg = SwapBytes16 (NvPublic->nvPublic.nameAlg);
254   WriteUnaligned32 ((UINT32 *)&NvPublic->nvPublic.attributes, SwapBytes32 (ReadUnaligned32 ((UINT32 *)&NvPublic->nvPublic.attributes)));
255   NvPublic->nvPublic.authPolicy.size = SwapBytes16 (NvPublic->nvPublic.authPolicy.size);
256   Buffer = (UINT8 *)&RecvBuffer.NvPublic.nvPublic.authPolicy;
257   Buffer += sizeof(UINT16) + NvPublic->nvPublic.authPolicy.size;
258   NvPublic->nvPublic.dataSize = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
259 
260   CopyMem (NvName->name, (UINT8 *)&RecvBuffer + sizeof(TPM2_RESPONSE_HEADER) + sizeof(UINT16) + NvPublicSize + sizeof(UINT16), NvNameSize);
261   NvName->size = NvNameSize;
262 
263   return EFI_SUCCESS;
264 }
265 
266 /**
267   This command defines the attributes of an NV Index and causes the TPM to
268   reserve space to hold the data associated with the index.
269   If a definition already exists at the index, the TPM will return TPM_RC_NV_DEFINED.
270 
271   @param[in]  AuthHandle         TPM_RH_OWNER or TPM_RH_PLATFORM+{PP}.
272   @param[in]  AuthSession        Auth Session context
273   @param[in]  Auth               The authorization data.
274   @param[in]  NvPublic           The public area of the index.
275 
276   @retval EFI_SUCCESS            Operation completed successfully.
277   @retval EFI_DEVICE_ERROR       The command was unsuccessful.
278   @retval EFI_ALREADY_STARTED    The command was returned successfully, but NvIndex is already defined.
279 **/
280 EFI_STATUS
281 EFIAPI
Tpm2NvDefineSpace(IN TPMI_RH_PROVISION AuthHandle,IN TPMS_AUTH_COMMAND * AuthSession,OPTIONAL IN TPM2B_AUTH * Auth,IN TPM2B_NV_PUBLIC * NvPublic)282 Tpm2NvDefineSpace (
283   IN      TPMI_RH_PROVISION         AuthHandle,
284   IN      TPMS_AUTH_COMMAND         *AuthSession, OPTIONAL
285   IN      TPM2B_AUTH                *Auth,
286   IN      TPM2B_NV_PUBLIC           *NvPublic
287   )
288 {
289   EFI_STATUS                        Status;
290   TPM2_NV_DEFINESPACE_COMMAND       SendBuffer;
291   TPM2_NV_DEFINESPACE_RESPONSE      RecvBuffer;
292   UINT32                            SendBufferSize;
293   UINT32                            RecvBufferSize;
294   UINT16                            NvPublicSize;
295   UINT8                             *Buffer;
296   UINT32                            SessionInfoSize;
297   TPM_RC                            ResponseCode;
298 
299   //
300   // Construct command
301   //
302   SendBuffer.Header.tag = SwapBytes16(TPM_ST_SESSIONS);
303   SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_NV_DefineSpace);
304   SendBuffer.AuthHandle = SwapBytes32 (AuthHandle);
305 
306   //
307   // Add in Auth session
308   //
309   Buffer = (UINT8 *)&SendBuffer.AuthSession;
310 
311   // sessionInfoSize
312   SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
313   Buffer += SessionInfoSize;
314   SendBuffer.AuthSessionSize = SwapBytes32(SessionInfoSize);
315 
316   //
317   // IndexAuth
318   //
319   WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(Auth->size));
320   Buffer += sizeof(UINT16);
321   CopyMem(Buffer, Auth->buffer, Auth->size);
322   Buffer += Auth->size;
323 
324   //
325   // NvPublic
326   //
327   NvPublicSize = NvPublic->size;
328 
329   WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (NvPublicSize));
330   Buffer += sizeof(UINT16);
331   WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32 (NvPublic->nvPublic.nvIndex));
332   Buffer += sizeof(UINT32);
333   WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (NvPublic->nvPublic.nameAlg));
334   Buffer += sizeof(UINT16);
335   WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32 (ReadUnaligned32 ((UINT32 *)&NvPublic->nvPublic.attributes)));
336   Buffer += sizeof(UINT32);
337   WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (NvPublic->nvPublic.authPolicy.size));
338   Buffer += sizeof(UINT16);
339   CopyMem (Buffer, NvPublic->nvPublic.authPolicy.buffer, NvPublic->nvPublic.authPolicy.size);
340   Buffer += NvPublic->nvPublic.authPolicy.size;
341   WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (NvPublic->nvPublic.dataSize));
342   Buffer += sizeof(UINT16);
343 
344   SendBufferSize = (UINT32)(Buffer - (UINT8 *)&SendBuffer);
345   SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);
346 
347   //
348   // send Tpm command
349   //
350   RecvBufferSize = sizeof (RecvBuffer);
351   Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);
352   if (EFI_ERROR (Status)) {
353     goto Done;
354   }
355 
356   if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {
357     DEBUG ((EFI_D_ERROR, "Tpm2NvDefineSpace - RecvBufferSize Error - %x\n", RecvBufferSize));
358     Status = EFI_DEVICE_ERROR;
359     goto Done;
360   }
361 
362   ResponseCode = SwapBytes32(RecvBuffer.Header.responseCode);
363   if (ResponseCode != TPM_RC_SUCCESS) {
364     DEBUG ((EFI_D_ERROR, "Tpm2NvDefineSpace - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));
365   }
366   switch (ResponseCode) {
367   case TPM_RC_SUCCESS:
368     // return data
369     break;
370   case TPM_RC_SIZE + RC_NV_DefineSpace_publicInfo:
371   case TPM_RC_SIZE + RC_NV_DefineSpace_auth:
372     Status = EFI_BAD_BUFFER_SIZE;
373     break;
374   case TPM_RC_ATTRIBUTES:
375   case TPM_RC_ATTRIBUTES + RC_NV_DefineSpace_publicInfo:
376     Status = EFI_UNSUPPORTED;
377     break;
378   case TPM_RC_ATTRIBUTES + RC_NV_DefineSpace_authHandle:
379     Status = EFI_INVALID_PARAMETER;
380     break;
381   case TPM_RC_NV_DEFINED:
382     Status = EFI_ALREADY_STARTED;
383     break;
384   case TPM_RC_VALUE + RC_NV_DefineSpace_publicInfo:
385   case TPM_RC_VALUE + RC_NV_DefineSpace_authHandle:
386     Status = EFI_INVALID_PARAMETER;
387     break;
388   case TPM_RC_NV_SPACE:
389     Status = EFI_OUT_OF_RESOURCES;
390     break;
391   default:
392     Status = EFI_DEVICE_ERROR;
393     break;
394   }
395 
396 Done:
397   //
398   // Clear AuthSession Content
399   //
400   ZeroMem (&SendBuffer, sizeof(SendBuffer));
401   ZeroMem (&RecvBuffer, sizeof(RecvBuffer));
402   return Status;
403 }
404 
405 /**
406   This command removes an index from the TPM.
407 
408   @param[in]  AuthHandle         TPM_RH_OWNER or TPM_RH_PLATFORM+{PP}.
409   @param[in]  NvIndex            The NV Index.
410   @param[in]  AuthSession        Auth Session context
411 
412   @retval EFI_SUCCESS            Operation completed successfully.
413   @retval EFI_DEVICE_ERROR       The command was unsuccessful.
414   @retval EFI_NOT_FOUND          The command was returned successfully, but NvIndex is not found.
415 **/
416 EFI_STATUS
417 EFIAPI
Tpm2NvUndefineSpace(IN TPMI_RH_PROVISION AuthHandle,IN TPMI_RH_NV_INDEX NvIndex,IN TPMS_AUTH_COMMAND * AuthSession OPTIONAL)418 Tpm2NvUndefineSpace (
419   IN      TPMI_RH_PROVISION         AuthHandle,
420   IN      TPMI_RH_NV_INDEX          NvIndex,
421   IN      TPMS_AUTH_COMMAND         *AuthSession OPTIONAL
422   )
423 {
424   EFI_STATUS                        Status;
425   TPM2_NV_UNDEFINESPACE_COMMAND     SendBuffer;
426   TPM2_NV_UNDEFINESPACE_RESPONSE    RecvBuffer;
427   UINT32                            SendBufferSize;
428   UINT32                            RecvBufferSize;
429   UINT8                             *Buffer;
430   UINT32                            SessionInfoSize;
431   TPM_RC                            ResponseCode;
432 
433   //
434   // Construct command
435   //
436   SendBuffer.Header.tag = SwapBytes16(TPM_ST_SESSIONS);
437   SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_NV_UndefineSpace);
438 
439   SendBuffer.AuthHandle = SwapBytes32 (AuthHandle);
440   SendBuffer.NvIndex = SwapBytes32 (NvIndex);
441 
442   //
443   // Add in Auth session
444   //
445   Buffer = (UINT8 *)&SendBuffer.AuthSession;
446 
447   // sessionInfoSize
448   SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
449   Buffer += SessionInfoSize;
450   SendBuffer.AuthSessionSize = SwapBytes32(SessionInfoSize);
451 
452   SendBufferSize = (UINT32)(Buffer - (UINT8 *)&SendBuffer);
453   SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);
454 
455   //
456   // send Tpm command
457   //
458   RecvBufferSize = sizeof (RecvBuffer);
459   Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);
460   if (EFI_ERROR (Status)) {
461     goto Done;
462   }
463 
464   if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {
465     DEBUG ((EFI_D_ERROR, "Tpm2NvUndefineSpace - RecvBufferSize Error - %x\n", RecvBufferSize));
466     Status = EFI_DEVICE_ERROR;
467     goto Done;
468   }
469 
470   ResponseCode = SwapBytes32(RecvBuffer.Header.responseCode);
471   if (ResponseCode != TPM_RC_SUCCESS) {
472     DEBUG ((EFI_D_ERROR, "Tpm2NvUndefineSpace - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));
473   }
474   switch (ResponseCode) {
475   case TPM_RC_SUCCESS:
476     // return data
477     break;
478   case TPM_RC_ATTRIBUTES:
479   case TPM_RC_ATTRIBUTES + RC_NV_UndefineSpace_nvIndex:
480     Status = EFI_UNSUPPORTED;
481     break;
482   case TPM_RC_NV_AUTHORIZATION:
483     Status = EFI_SECURITY_VIOLATION;
484     break;
485   case TPM_RC_HANDLE + RC_NV_UndefineSpace_nvIndex: // TPM_RC_NV_DEFINED:
486     Status = EFI_NOT_FOUND;
487     break;
488   case TPM_RC_HANDLE + RC_NV_UndefineSpace_authHandle: // TPM_RC_NV_DEFINED:
489     Status = EFI_INVALID_PARAMETER;
490     break;
491   case TPM_RC_VALUE + RC_NV_UndefineSpace_authHandle:
492   case TPM_RC_VALUE + RC_NV_UndefineSpace_nvIndex:
493     Status = EFI_INVALID_PARAMETER;
494     break;
495   default:
496     Status = EFI_DEVICE_ERROR;
497     break;
498   }
499 
500 Done:
501   //
502   // Clear AuthSession Content
503   //
504   ZeroMem (&SendBuffer, sizeof(SendBuffer));
505   ZeroMem (&RecvBuffer, sizeof(RecvBuffer));
506   return Status;
507 }
508 
509 /**
510   This command reads a value from an area in NV memory previously defined by TPM2_NV_DefineSpace().
511 
512   @param[in]     AuthHandle         the handle indicating the source of the authorization value.
513   @param[in]     NvIndex            The index to be read.
514   @param[in]     AuthSession        Auth Session context
515   @param[in]     Size               Number of bytes to read.
516   @param[in]     Offset             Byte offset into the area.
517   @param[in,out] OutData            The data read.
518 
519   @retval EFI_SUCCESS            Operation completed successfully.
520   @retval EFI_DEVICE_ERROR       The command was unsuccessful.
521   @retval EFI_NOT_FOUND          The command was returned successfully, but NvIndex is not found.
522 **/
523 EFI_STATUS
524 EFIAPI
Tpm2NvRead(IN TPMI_RH_NV_AUTH AuthHandle,IN TPMI_RH_NV_INDEX NvIndex,IN TPMS_AUTH_COMMAND * AuthSession,OPTIONAL IN UINT16 Size,IN UINT16 Offset,IN OUT TPM2B_MAX_BUFFER * OutData)525 Tpm2NvRead (
526   IN      TPMI_RH_NV_AUTH           AuthHandle,
527   IN      TPMI_RH_NV_INDEX          NvIndex,
528   IN      TPMS_AUTH_COMMAND         *AuthSession, OPTIONAL
529   IN      UINT16                    Size,
530   IN      UINT16                    Offset,
531   IN OUT  TPM2B_MAX_BUFFER          *OutData
532   )
533 {
534   EFI_STATUS                        Status;
535   TPM2_NV_READ_COMMAND              SendBuffer;
536   TPM2_NV_READ_RESPONSE             RecvBuffer;
537   UINT32                            SendBufferSize;
538   UINT32                            RecvBufferSize;
539   UINT8                             *Buffer;
540   UINT32                            SessionInfoSize;
541   TPM_RC                            ResponseCode;
542 
543   //
544   // Construct command
545   //
546   SendBuffer.Header.tag = SwapBytes16(TPM_ST_SESSIONS);
547   SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_NV_Read);
548 
549   SendBuffer.AuthHandle = SwapBytes32 (AuthHandle);
550   SendBuffer.NvIndex = SwapBytes32 (NvIndex);
551 
552   //
553   // Add in Auth session
554   //
555   Buffer = (UINT8 *)&SendBuffer.AuthSession;
556 
557   // sessionInfoSize
558   SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
559   Buffer += SessionInfoSize;
560   SendBuffer.AuthSessionSize = SwapBytes32(SessionInfoSize);
561 
562   WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Size));
563   Buffer += sizeof(UINT16);
564   WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Offset));
565   Buffer += sizeof(UINT16);
566 
567   SendBufferSize = (UINT32)(Buffer - (UINT8 *)&SendBuffer);
568   SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);
569 
570   //
571   // send Tpm command
572   //
573   RecvBufferSize = sizeof (RecvBuffer);
574   Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);
575   if (EFI_ERROR (Status)) {
576     goto Done;
577   }
578 
579   if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {
580     DEBUG ((EFI_D_ERROR, "Tpm2NvRead - RecvBufferSize Error - %x\n", RecvBufferSize));
581     Status = EFI_DEVICE_ERROR;
582     goto Done;
583   }
584   ResponseCode = SwapBytes32(RecvBuffer.Header.responseCode);
585   if (ResponseCode != TPM_RC_SUCCESS) {
586     DEBUG ((EFI_D_ERROR, "Tpm2NvRead - responseCode - %x\n", ResponseCode));
587   }
588   switch (ResponseCode) {
589   case TPM_RC_SUCCESS:
590     // return data
591     break;
592   case TPM_RC_NV_AUTHORIZATION:
593     Status = EFI_SECURITY_VIOLATION;
594     break;
595   case TPM_RC_NV_LOCKED:
596     Status = EFI_ACCESS_DENIED;
597     break;
598   case TPM_RC_NV_RANGE:
599     Status = EFI_BAD_BUFFER_SIZE;
600     break;
601   case TPM_RC_NV_UNINITIALIZED:
602     Status = EFI_NOT_READY;
603     break;
604   case TPM_RC_HANDLE + RC_NV_Read_nvIndex: // TPM_RC_NV_DEFINED:
605     Status = EFI_NOT_FOUND;
606     break;
607   case TPM_RC_HANDLE + RC_NV_Read_authHandle: // TPM_RC_NV_DEFINED:
608     Status = EFI_INVALID_PARAMETER;
609     break;
610   case TPM_RC_VALUE + RC_NV_Read_nvIndex:
611   case TPM_RC_VALUE + RC_NV_Read_authHandle:
612     Status = EFI_INVALID_PARAMETER;
613     break;
614   case TPM_RC_BAD_AUTH + RC_NV_Read_authHandle + TPM_RC_S:
615     Status = EFI_INVALID_PARAMETER;
616     break;
617   case TPM_RC_AUTH_UNAVAILABLE:
618     Status = EFI_INVALID_PARAMETER;
619     break;
620   case TPM_RC_AUTH_FAIL + RC_NV_Read_authHandle + TPM_RC_S:
621     Status = EFI_INVALID_PARAMETER;
622     break;
623   case TPM_RC_ATTRIBUTES + RC_NV_Read_authHandle + TPM_RC_S:
624     Status = EFI_UNSUPPORTED;
625     break;
626   default:
627     Status = EFI_DEVICE_ERROR;
628     break;
629   }
630   if (Status != EFI_SUCCESS) {
631     goto Done;
632   }
633 
634   //
635   // Return the response
636   //
637   OutData->size = SwapBytes16 (RecvBuffer.Data.size);
638   if (OutData->size > MAX_DIGEST_BUFFER) {
639     DEBUG ((DEBUG_ERROR, "Tpm2NvRead - OutData->size error %x\n", OutData->size));
640     Status = EFI_DEVICE_ERROR;
641     goto Done;
642   }
643 
644   CopyMem (OutData->buffer, &RecvBuffer.Data.buffer, OutData->size);
645 
646 Done:
647   //
648   // Clear AuthSession Content
649   //
650   ZeroMem (&SendBuffer, sizeof(SendBuffer));
651   ZeroMem (&RecvBuffer, sizeof(RecvBuffer));
652   return Status;
653 }
654 
655 /**
656   This command writes a value to an area in NV memory that was previously defined by TPM2_NV_DefineSpace().
657 
658   @param[in]  AuthHandle         the handle indicating the source of the authorization value.
659   @param[in]  NvIndex            The NV Index of the area to write.
660   @param[in]  AuthSession        Auth Session context
661   @param[in]  InData             The data to write.
662   @param[in]  Offset             The offset into the NV Area.
663 
664   @retval EFI_SUCCESS            Operation completed successfully.
665   @retval EFI_DEVICE_ERROR       The command was unsuccessful.
666   @retval EFI_NOT_FOUND          The command was returned successfully, but NvIndex is not found.
667 **/
668 EFI_STATUS
669 EFIAPI
Tpm2NvWrite(IN TPMI_RH_NV_AUTH AuthHandle,IN TPMI_RH_NV_INDEX NvIndex,IN TPMS_AUTH_COMMAND * AuthSession,OPTIONAL IN TPM2B_MAX_BUFFER * InData,IN UINT16 Offset)670 Tpm2NvWrite (
671   IN      TPMI_RH_NV_AUTH           AuthHandle,
672   IN      TPMI_RH_NV_INDEX          NvIndex,
673   IN      TPMS_AUTH_COMMAND         *AuthSession, OPTIONAL
674   IN      TPM2B_MAX_BUFFER          *InData,
675   IN      UINT16                    Offset
676   )
677 {
678   EFI_STATUS                        Status;
679   TPM2_NV_WRITE_COMMAND             SendBuffer;
680   TPM2_NV_WRITE_RESPONSE            RecvBuffer;
681   UINT32                            SendBufferSize;
682   UINT32                            RecvBufferSize;
683   UINT8                             *Buffer;
684   UINT32                            SessionInfoSize;
685   TPM_RC                            ResponseCode;
686 
687   //
688   // Construct command
689   //
690   SendBuffer.Header.tag = SwapBytes16(TPM_ST_SESSIONS);
691   SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_NV_Write);
692 
693   SendBuffer.AuthHandle = SwapBytes32 (AuthHandle);
694   SendBuffer.NvIndex = SwapBytes32 (NvIndex);
695 
696   //
697   // Add in Auth session
698   //
699   Buffer = (UINT8 *)&SendBuffer.AuthSession;
700 
701   // sessionInfoSize
702   SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
703   Buffer += SessionInfoSize;
704   SendBuffer.AuthSessionSize = SwapBytes32(SessionInfoSize);
705 
706   WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (InData->size));
707   Buffer += sizeof(UINT16);
708   CopyMem (Buffer, InData->buffer, InData->size);
709   Buffer += InData->size;
710   WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Offset));
711   Buffer += sizeof(UINT16);
712 
713   SendBufferSize = (UINT32) (Buffer - (UINT8 *)&SendBuffer);
714   SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);
715 
716   //
717   // send Tpm command
718   //
719   RecvBufferSize = sizeof (RecvBuffer);
720   Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);
721   if (EFI_ERROR (Status)) {
722     goto Done;
723   }
724 
725   if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {
726     DEBUG ((EFI_D_ERROR, "Tpm2NvWrite - RecvBufferSize Error - %x\n", RecvBufferSize));
727     Status = EFI_DEVICE_ERROR;
728     goto Done;
729   }
730   ResponseCode = SwapBytes32(RecvBuffer.Header.responseCode);
731   if (ResponseCode != TPM_RC_SUCCESS) {
732     DEBUG ((EFI_D_ERROR, "Tpm2NvWrite - responseCode - %x\n", ResponseCode));
733   }
734   switch (ResponseCode) {
735   case TPM_RC_SUCCESS:
736     // return data
737     break;
738   case TPM_RC_ATTRIBUTES:
739     Status = EFI_UNSUPPORTED;
740     break;
741   case TPM_RC_NV_AUTHORIZATION:
742     Status = EFI_SECURITY_VIOLATION;
743     break;
744   case TPM_RC_NV_LOCKED:
745     Status = EFI_ACCESS_DENIED;
746     break;
747   case TPM_RC_NV_RANGE:
748     Status = EFI_BAD_BUFFER_SIZE;
749     break;
750   case TPM_RC_HANDLE + RC_NV_Write_nvIndex: // TPM_RC_NV_DEFINED:
751     Status = EFI_NOT_FOUND;
752     break;
753   case TPM_RC_HANDLE + RC_NV_Write_authHandle: // TPM_RC_NV_DEFINED:
754     Status = EFI_INVALID_PARAMETER;
755     break;
756   case TPM_RC_VALUE + RC_NV_Write_nvIndex:
757   case TPM_RC_VALUE + RC_NV_Write_authHandle:
758     Status = EFI_INVALID_PARAMETER;
759     break;
760   case TPM_RC_BAD_AUTH + RC_NV_Write_authHandle + TPM_RC_S:
761     Status = EFI_INVALID_PARAMETER;
762     break;
763   case TPM_RC_AUTH_UNAVAILABLE:
764     Status = EFI_INVALID_PARAMETER;
765     break;
766   case TPM_RC_AUTH_FAIL + RC_NV_Write_authHandle + TPM_RC_S:
767     Status = EFI_INVALID_PARAMETER;
768     break;
769   case TPM_RC_ATTRIBUTES + RC_NV_Write_authHandle + TPM_RC_S:
770     Status = EFI_UNSUPPORTED;
771     break;
772   default:
773     Status = EFI_DEVICE_ERROR;
774     break;
775   }
776 
777 Done:
778   //
779   // Clear AuthSession Content
780   //
781   ZeroMem (&SendBuffer, sizeof(SendBuffer));
782   ZeroMem (&RecvBuffer, sizeof(RecvBuffer));
783   return Status;
784 }
785 
786 /**
787   This command may be used to prevent further reads of the Index until the next TPM2_Startup (TPM_SU_CLEAR).
788 
789   @param[in]  AuthHandle         the handle indicating the source of the authorization value.
790   @param[in]  NvIndex            The NV Index of the area to lock.
791   @param[in]  AuthSession        Auth Session context
792 
793   @retval EFI_SUCCESS            Operation completed successfully.
794   @retval EFI_DEVICE_ERROR       The command was unsuccessful.
795   @retval EFI_NOT_FOUND          The command was returned successfully, but NvIndex is not found.
796 **/
797 EFI_STATUS
798 EFIAPI
Tpm2NvReadLock(IN TPMI_RH_NV_AUTH AuthHandle,IN TPMI_RH_NV_INDEX NvIndex,IN TPMS_AUTH_COMMAND * AuthSession OPTIONAL)799 Tpm2NvReadLock (
800   IN      TPMI_RH_NV_AUTH           AuthHandle,
801   IN      TPMI_RH_NV_INDEX          NvIndex,
802   IN      TPMS_AUTH_COMMAND         *AuthSession OPTIONAL
803   )
804 {
805   EFI_STATUS                        Status;
806   TPM2_NV_READLOCK_COMMAND          SendBuffer;
807   TPM2_NV_READLOCK_RESPONSE         RecvBuffer;
808   UINT32                            SendBufferSize;
809   UINT32                            RecvBufferSize;
810   UINT8                             *Buffer;
811   UINT32                            SessionInfoSize;
812   TPM_RC                            ResponseCode;
813 
814   //
815   // Construct command
816   //
817   SendBuffer.Header.tag = SwapBytes16(TPM_ST_SESSIONS);
818   SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_NV_ReadLock);
819 
820   SendBuffer.AuthHandle = SwapBytes32 (AuthHandle);
821   SendBuffer.NvIndex = SwapBytes32 (NvIndex);
822 
823   //
824   // Add in Auth session
825   //
826   Buffer = (UINT8 *)&SendBuffer.AuthSession;
827 
828   // sessionInfoSize
829   SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
830   Buffer += SessionInfoSize;
831   SendBuffer.AuthSessionSize = SwapBytes32(SessionInfoSize);
832 
833   SendBufferSize = (UINT32)(Buffer - (UINT8 *)&SendBuffer);
834   SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);
835 
836   //
837   // send Tpm command
838   //
839   RecvBufferSize = sizeof (RecvBuffer);
840   Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);
841   if (EFI_ERROR (Status)) {
842     goto Done;
843   }
844 
845   if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {
846     DEBUG ((EFI_D_ERROR, "Tpm2NvReadLock - RecvBufferSize Error - %x\n", RecvBufferSize));
847     Status = EFI_DEVICE_ERROR;
848     goto Done;
849   }
850 
851   ResponseCode = SwapBytes32(RecvBuffer.Header.responseCode);
852   if (ResponseCode != TPM_RC_SUCCESS) {
853     DEBUG ((EFI_D_ERROR, "Tpm2NvReadLock - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));
854   }
855   switch (ResponseCode) {
856   case TPM_RC_SUCCESS:
857     // return data
858     break;
859   default:
860     Status = EFI_DEVICE_ERROR;
861     break;
862   }
863 
864 Done:
865   //
866   // Clear AuthSession Content
867   //
868   ZeroMem (&SendBuffer, sizeof(SendBuffer));
869   ZeroMem (&RecvBuffer, sizeof(RecvBuffer));
870   return Status;
871 }
872 
873 /**
874   This command may be used to inhibit further writes of the Index.
875 
876   @param[in]  AuthHandle         the handle indicating the source of the authorization value.
877   @param[in]  NvIndex            The NV Index of the area to lock.
878   @param[in]  AuthSession        Auth Session context
879 
880   @retval EFI_SUCCESS            Operation completed successfully.
881   @retval EFI_DEVICE_ERROR       The command was unsuccessful.
882   @retval EFI_NOT_FOUND          The command was returned successfully, but NvIndex is not found.
883 **/
884 EFI_STATUS
885 EFIAPI
Tpm2NvWriteLock(IN TPMI_RH_NV_AUTH AuthHandle,IN TPMI_RH_NV_INDEX NvIndex,IN TPMS_AUTH_COMMAND * AuthSession OPTIONAL)886 Tpm2NvWriteLock (
887   IN      TPMI_RH_NV_AUTH           AuthHandle,
888   IN      TPMI_RH_NV_INDEX          NvIndex,
889   IN      TPMS_AUTH_COMMAND         *AuthSession OPTIONAL
890   )
891 {
892   EFI_STATUS                        Status;
893   TPM2_NV_WRITELOCK_COMMAND         SendBuffer;
894   TPM2_NV_WRITELOCK_RESPONSE        RecvBuffer;
895   UINT32                            SendBufferSize;
896   UINT32                            RecvBufferSize;
897   UINT8                             *Buffer;
898   UINT32                            SessionInfoSize;
899   TPM_RC                            ResponseCode;
900 
901   //
902   // Construct command
903   //
904   SendBuffer.Header.tag = SwapBytes16(TPM_ST_SESSIONS);
905   SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_NV_WriteLock);
906 
907   SendBuffer.AuthHandle = SwapBytes32 (AuthHandle);
908   SendBuffer.NvIndex = SwapBytes32 (NvIndex);
909 
910   //
911   // Add in Auth session
912   //
913   Buffer = (UINT8 *)&SendBuffer.AuthSession;
914 
915   // sessionInfoSize
916   SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
917   Buffer += SessionInfoSize;
918   SendBuffer.AuthSessionSize = SwapBytes32(SessionInfoSize);
919 
920   SendBufferSize = (UINT32)(Buffer - (UINT8 *)&SendBuffer);
921   SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);
922 
923   //
924   // send Tpm command
925   //
926   RecvBufferSize = sizeof (RecvBuffer);
927   Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);
928   if (EFI_ERROR (Status)) {
929     goto Done;
930   }
931 
932   if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {
933     DEBUG ((EFI_D_ERROR, "Tpm2NvWriteLock - RecvBufferSize Error - %x\n", RecvBufferSize));
934     Status = EFI_DEVICE_ERROR;
935     goto Done;
936   }
937 
938   ResponseCode = SwapBytes32(RecvBuffer.Header.responseCode);
939   if (ResponseCode != TPM_RC_SUCCESS) {
940     DEBUG ((EFI_D_ERROR, "Tpm2NvWriteLock - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));
941   }
942   switch (ResponseCode) {
943   case TPM_RC_SUCCESS:
944     // return data
945     break;
946   default:
947     Status = EFI_DEVICE_ERROR;
948     break;
949   }
950 
951 Done:
952   //
953   // Clear AuthSession Content
954   //
955   ZeroMem (&SendBuffer, sizeof(SendBuffer));
956   ZeroMem (&RecvBuffer, sizeof(RecvBuffer));
957   return Status;
958 }
959 
960 /**
961   The command will SET TPMA_NV_WRITELOCKED for all indexes that have their TPMA_NV_GLOBALLOCK attribute SET.
962 
963   @param[in]  AuthHandle         TPM_RH_OWNER or TPM_RH_PLATFORM+{PP}.
964   @param[in]  AuthSession        Auth Session context
965 
966   @retval EFI_SUCCESS            Operation completed successfully.
967   @retval EFI_DEVICE_ERROR       The command was unsuccessful.
968   @retval EFI_NOT_FOUND          The command was returned successfully, but NvIndex is not found.
969 **/
970 EFI_STATUS
971 EFIAPI
Tpm2NvGlobalWriteLock(IN TPMI_RH_PROVISION AuthHandle,IN TPMS_AUTH_COMMAND * AuthSession OPTIONAL)972 Tpm2NvGlobalWriteLock (
973   IN      TPMI_RH_PROVISION         AuthHandle,
974   IN      TPMS_AUTH_COMMAND         *AuthSession OPTIONAL
975   )
976 {
977   EFI_STATUS                        Status;
978   TPM2_NV_GLOBALWRITELOCK_COMMAND   SendBuffer;
979   TPM2_NV_GLOBALWRITELOCK_RESPONSE  RecvBuffer;
980   UINT32                            SendBufferSize;
981   UINT32                            RecvBufferSize;
982   UINT8                             *Buffer;
983   UINT32                            SessionInfoSize;
984   TPM_RC                            ResponseCode;
985 
986   //
987   // Construct command
988   //
989   SendBuffer.Header.tag = SwapBytes16(TPM_ST_SESSIONS);
990   SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_NV_GlobalWriteLock);
991 
992   SendBuffer.AuthHandle = SwapBytes32 (AuthHandle);
993 
994   //
995   // Add in Auth session
996   //
997   Buffer = (UINT8 *)&SendBuffer.AuthSession;
998 
999   // sessionInfoSize
1000   SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
1001   Buffer += SessionInfoSize;
1002   SendBuffer.AuthSessionSize = SwapBytes32(SessionInfoSize);
1003 
1004   SendBufferSize = (UINT32)(Buffer - (UINT8 *)&SendBuffer);
1005   SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);
1006 
1007   //
1008   // send Tpm command
1009   //
1010   RecvBufferSize = sizeof (RecvBuffer);
1011   Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);
1012   if (EFI_ERROR (Status)) {
1013     goto Done;
1014   }
1015 
1016   if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {
1017     DEBUG ((EFI_D_ERROR, "Tpm2NvGlobalWriteLock - RecvBufferSize Error - %x\n", RecvBufferSize));
1018     Status = EFI_DEVICE_ERROR;
1019     goto Done;
1020   }
1021 
1022   ResponseCode = SwapBytes32(RecvBuffer.Header.responseCode);
1023   if (ResponseCode != TPM_RC_SUCCESS) {
1024     DEBUG ((EFI_D_ERROR, "Tpm2NvGlobalWriteLock - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));
1025   }
1026   switch (ResponseCode) {
1027   case TPM_RC_SUCCESS:
1028     // return data
1029     break;
1030   default:
1031     Status = EFI_DEVICE_ERROR;
1032     break;
1033   }
1034 
1035 Done:
1036   //
1037   // Clear AuthSession Content
1038   //
1039   ZeroMem (&SendBuffer, sizeof(SendBuffer));
1040   ZeroMem (&RecvBuffer, sizeof(RecvBuffer));
1041   return Status;
1042 }
1043