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