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