1 /** @file
2 Implement TPM2 NVStorage related command.
3
4 Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved. <BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 **/
14
15 #include <IndustryStandard/UefiTcgPlatform.h>
16 #include <Library/Tpm2CommandLib.h>
17 #include <Library/Tpm2DeviceLib.h>
18 #include <Library/BaseMemoryLib.h>
19 #include <Library/BaseLib.h>
20 #include <Library/DebugLib.h>
21
22 #pragma pack(1)
23
24 #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
Tpm2NvReadPublic(IN TPMI_RH_NV_INDEX NvIndex,OUT TPM2B_NV_PUBLIC * NvPublic,OUT TPM2B_NAME * NvName)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 *)&RecvBuffer.NvPublic.nvPublic.authPolicy;
254 Buffer += sizeof(UINT16) + NvPublic->nvPublic.authPolicy.size;
255 NvPublic->nvPublic.dataSize = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
256
257 CopyMem (NvName->name, (UINT8 *)&RecvBuffer + sizeof(TPM2_RESPONSE_HEADER) + sizeof(UINT16) + NvPublicSize + sizeof(UINT16), 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
Tpm2NvDefineSpace(IN TPMI_RH_PROVISION AuthHandle,IN TPMS_AUTH_COMMAND * AuthSession,OPTIONAL IN TPM2B_AUTH * Auth,IN TPM2B_NV_PUBLIC * NvPublic)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 goto Done;
351 }
352
353 if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {
354 DEBUG ((EFI_D_ERROR, "Tpm2NvDefineSpace - RecvBufferSize Error - %x\n", RecvBufferSize));
355 Status = EFI_DEVICE_ERROR;
356 goto Done;
357 }
358
359 ResponseCode = SwapBytes32(RecvBuffer.Header.responseCode);
360 if (ResponseCode != TPM_RC_SUCCESS) {
361 DEBUG ((EFI_D_ERROR, "Tpm2NvDefineSpace - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));
362 }
363 switch (ResponseCode) {
364 case TPM_RC_SUCCESS:
365 // return data
366 break;
367 case TPM_RC_SIZE + RC_NV_DefineSpace_publicInfo:
368 case TPM_RC_SIZE + RC_NV_DefineSpace_auth:
369 Status = EFI_BAD_BUFFER_SIZE;
370 break;
371 case TPM_RC_ATTRIBUTES:
372 case TPM_RC_ATTRIBUTES + RC_NV_DefineSpace_publicInfo:
373 Status = EFI_UNSUPPORTED;
374 break;
375 case TPM_RC_ATTRIBUTES + RC_NV_DefineSpace_authHandle:
376 Status = EFI_INVALID_PARAMETER;
377 break;
378 case TPM_RC_NV_DEFINED:
379 Status = EFI_ALREADY_STARTED;
380 break;
381 case TPM_RC_VALUE + RC_NV_DefineSpace_publicInfo:
382 case TPM_RC_VALUE + RC_NV_DefineSpace_authHandle:
383 Status = EFI_INVALID_PARAMETER;
384 break;
385 case TPM_RC_NV_SPACE:
386 Status = EFI_OUT_OF_RESOURCES;
387 break;
388 default:
389 Status = EFI_DEVICE_ERROR;
390 break;
391 }
392
393 Done:
394 //
395 // Clear AuthSession Content
396 //
397 ZeroMem (&SendBuffer, sizeof(SendBuffer));
398 ZeroMem (&RecvBuffer, sizeof(RecvBuffer));
399 return Status;
400 }
401
402 /**
403 This command removes an index from the TPM.
404
405 @param[in] AuthHandle TPM_RH_OWNER or TPM_RH_PLATFORM+{PP}.
406 @param[in] NvIndex The NV Index.
407 @param[in] AuthSession Auth Session context
408
409 @retval EFI_SUCCESS Operation completed successfully.
410 @retval EFI_DEVICE_ERROR The command was unsuccessful.
411 @retval EFI_NOT_FOUND The command was returned successfully, but NvIndex is not found.
412 **/
413 EFI_STATUS
414 EFIAPI
Tpm2NvUndefineSpace(IN TPMI_RH_PROVISION AuthHandle,IN TPMI_RH_NV_INDEX NvIndex,IN TPMS_AUTH_COMMAND * AuthSession OPTIONAL)415 Tpm2NvUndefineSpace (
416 IN TPMI_RH_PROVISION AuthHandle,
417 IN TPMI_RH_NV_INDEX NvIndex,
418 IN TPMS_AUTH_COMMAND *AuthSession OPTIONAL
419 )
420 {
421 EFI_STATUS Status;
422 TPM2_NV_UNDEFINESPACE_COMMAND SendBuffer;
423 TPM2_NV_UNDEFINESPACE_RESPONSE RecvBuffer;
424 UINT32 SendBufferSize;
425 UINT32 RecvBufferSize;
426 UINT8 *Buffer;
427 UINT32 SessionInfoSize;
428 TPM_RC ResponseCode;
429
430 //
431 // Construct command
432 //
433 SendBuffer.Header.tag = SwapBytes16(TPM_ST_SESSIONS);
434 SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_NV_UndefineSpace);
435
436 SendBuffer.AuthHandle = SwapBytes32 (AuthHandle);
437 SendBuffer.NvIndex = SwapBytes32 (NvIndex);
438
439 //
440 // Add in Auth session
441 //
442 Buffer = (UINT8 *)&SendBuffer.AuthSession;
443
444 // sessionInfoSize
445 SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
446 Buffer += SessionInfoSize;
447 SendBuffer.AuthSessionSize = SwapBytes32(SessionInfoSize);
448
449 SendBufferSize = (UINT32)(Buffer - (UINT8 *)&SendBuffer);
450 SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);
451
452 //
453 // send Tpm command
454 //
455 RecvBufferSize = sizeof (RecvBuffer);
456 Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);
457 if (EFI_ERROR (Status)) {
458 goto Done;
459 }
460
461 if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {
462 DEBUG ((EFI_D_ERROR, "Tpm2NvUndefineSpace - RecvBufferSize Error - %x\n", RecvBufferSize));
463 Status = EFI_DEVICE_ERROR;
464 goto Done;
465 }
466
467 ResponseCode = SwapBytes32(RecvBuffer.Header.responseCode);
468 if (ResponseCode != TPM_RC_SUCCESS) {
469 DEBUG ((EFI_D_ERROR, "Tpm2NvUndefineSpace - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));
470 }
471 switch (ResponseCode) {
472 case TPM_RC_SUCCESS:
473 // return data
474 break;
475 case TPM_RC_ATTRIBUTES:
476 case TPM_RC_ATTRIBUTES + RC_NV_UndefineSpace_nvIndex:
477 Status = EFI_UNSUPPORTED;
478 break;
479 case TPM_RC_NV_AUTHORIZATION:
480 Status = EFI_SECURITY_VIOLATION;
481 break;
482 case TPM_RC_HANDLE + RC_NV_UndefineSpace_nvIndex: // TPM_RC_NV_DEFINED:
483 Status = EFI_NOT_FOUND;
484 break;
485 case TPM_RC_HANDLE + RC_NV_UndefineSpace_authHandle: // TPM_RC_NV_DEFINED:
486 Status = EFI_INVALID_PARAMETER;
487 break;
488 case TPM_RC_VALUE + RC_NV_UndefineSpace_authHandle:
489 case TPM_RC_VALUE + RC_NV_UndefineSpace_nvIndex:
490 Status = EFI_INVALID_PARAMETER;
491 break;
492 default:
493 Status = EFI_DEVICE_ERROR;
494 break;
495 }
496
497 Done:
498 //
499 // Clear AuthSession Content
500 //
501 ZeroMem (&SendBuffer, sizeof(SendBuffer));
502 ZeroMem (&RecvBuffer, sizeof(RecvBuffer));
503 return Status;
504 }
505
506 /**
507 This command reads a value from an area in NV memory previously defined by TPM2_NV_DefineSpace().
508
509 @param[in] AuthHandle the handle indicating the source of the authorization value.
510 @param[in] NvIndex The index to be read.
511 @param[in] AuthSession Auth Session context
512 @param[in] Size Number of bytes to read.
513 @param[in] Offset Byte offset into the area.
514 @param[in,out] OutData The data read.
515
516 @retval EFI_SUCCESS Operation completed successfully.
517 @retval EFI_DEVICE_ERROR The command was unsuccessful.
518 @retval EFI_NOT_FOUND The command was returned successfully, but NvIndex is not found.
519 **/
520 EFI_STATUS
521 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)522 Tpm2NvRead (
523 IN TPMI_RH_NV_AUTH AuthHandle,
524 IN TPMI_RH_NV_INDEX NvIndex,
525 IN TPMS_AUTH_COMMAND *AuthSession, OPTIONAL
526 IN UINT16 Size,
527 IN UINT16 Offset,
528 IN OUT TPM2B_MAX_BUFFER *OutData
529 )
530 {
531 EFI_STATUS Status;
532 TPM2_NV_READ_COMMAND SendBuffer;
533 TPM2_NV_READ_RESPONSE RecvBuffer;
534 UINT32 SendBufferSize;
535 UINT32 RecvBufferSize;
536 UINT8 *Buffer;
537 UINT32 SessionInfoSize;
538 TPM_RC ResponseCode;
539
540 //
541 // Construct command
542 //
543 SendBuffer.Header.tag = SwapBytes16(TPM_ST_SESSIONS);
544 SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_NV_Read);
545
546 SendBuffer.AuthHandle = SwapBytes32 (AuthHandle);
547 SendBuffer.NvIndex = SwapBytes32 (NvIndex);
548
549 //
550 // Add in Auth session
551 //
552 Buffer = (UINT8 *)&SendBuffer.AuthSession;
553
554 // sessionInfoSize
555 SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
556 Buffer += SessionInfoSize;
557 SendBuffer.AuthSessionSize = SwapBytes32(SessionInfoSize);
558
559 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Size));
560 Buffer += sizeof(UINT16);
561 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Offset));
562 Buffer += sizeof(UINT16);
563
564 SendBufferSize = (UINT32)(Buffer - (UINT8 *)&SendBuffer);
565 SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);
566
567 //
568 // send Tpm command
569 //
570 RecvBufferSize = sizeof (RecvBuffer);
571 Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);
572 if (EFI_ERROR (Status)) {
573 goto Done;
574 }
575
576 if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {
577 DEBUG ((EFI_D_ERROR, "Tpm2NvRead - RecvBufferSize Error - %x\n", RecvBufferSize));
578 Status = EFI_DEVICE_ERROR;
579 goto Done;
580 }
581 ResponseCode = SwapBytes32(RecvBuffer.Header.responseCode);
582 if (ResponseCode != TPM_RC_SUCCESS) {
583 DEBUG ((EFI_D_ERROR, "Tpm2NvRead - responseCode - %x\n", ResponseCode));
584 }
585 switch (ResponseCode) {
586 case TPM_RC_SUCCESS:
587 // return data
588 break;
589 case TPM_RC_NV_AUTHORIZATION:
590 Status = EFI_SECURITY_VIOLATION;
591 break;
592 case TPM_RC_NV_LOCKED:
593 Status = EFI_ACCESS_DENIED;
594 break;
595 case TPM_RC_NV_RANGE:
596 Status = EFI_BAD_BUFFER_SIZE;
597 break;
598 case TPM_RC_NV_UNINITIALIZED:
599 Status = EFI_NOT_READY;
600 break;
601 case TPM_RC_HANDLE + RC_NV_Read_nvIndex: // TPM_RC_NV_DEFINED:
602 Status = EFI_NOT_FOUND;
603 break;
604 case TPM_RC_HANDLE + RC_NV_Read_authHandle: // TPM_RC_NV_DEFINED:
605 Status = EFI_INVALID_PARAMETER;
606 break;
607 case TPM_RC_VALUE + RC_NV_Read_nvIndex:
608 case TPM_RC_VALUE + RC_NV_Read_authHandle:
609 Status = EFI_INVALID_PARAMETER;
610 break;
611 case TPM_RC_BAD_AUTH + RC_NV_Read_authHandle + TPM_RC_S:
612 Status = EFI_INVALID_PARAMETER;
613 break;
614 case TPM_RC_AUTH_UNAVAILABLE:
615 Status = EFI_INVALID_PARAMETER;
616 break;
617 case TPM_RC_AUTH_FAIL + RC_NV_Read_authHandle + TPM_RC_S:
618 Status = EFI_INVALID_PARAMETER;
619 break;
620 case TPM_RC_ATTRIBUTES + RC_NV_Read_authHandle + TPM_RC_S:
621 Status = EFI_UNSUPPORTED;
622 break;
623 default:
624 Status = EFI_DEVICE_ERROR;
625 break;
626 }
627 if (Status != EFI_SUCCESS) {
628 goto Done;
629 }
630
631 //
632 // Return the response
633 //
634 OutData->size = SwapBytes16 (RecvBuffer.Data.size);
635 CopyMem (OutData->buffer, &RecvBuffer.Data.buffer, OutData->size);
636
637 Done:
638 //
639 // Clear AuthSession Content
640 //
641 ZeroMem (&SendBuffer, sizeof(SendBuffer));
642 ZeroMem (&RecvBuffer, sizeof(RecvBuffer));
643 return Status;
644 }
645
646 /**
647 This command writes a value to an area in NV memory that was previously defined by TPM2_NV_DefineSpace().
648
649 @param[in] AuthHandle the handle indicating the source of the authorization value.
650 @param[in] NvIndex The NV Index of the area to write.
651 @param[in] AuthSession Auth Session context
652 @param[in] InData The data to write.
653 @param[in] Offset The offset into the NV Area.
654
655 @retval EFI_SUCCESS Operation completed successfully.
656 @retval EFI_DEVICE_ERROR The command was unsuccessful.
657 @retval EFI_NOT_FOUND The command was returned successfully, but NvIndex is not found.
658 **/
659 EFI_STATUS
660 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)661 Tpm2NvWrite (
662 IN TPMI_RH_NV_AUTH AuthHandle,
663 IN TPMI_RH_NV_INDEX NvIndex,
664 IN TPMS_AUTH_COMMAND *AuthSession, OPTIONAL
665 IN TPM2B_MAX_BUFFER *InData,
666 IN UINT16 Offset
667 )
668 {
669 EFI_STATUS Status;
670 TPM2_NV_WRITE_COMMAND SendBuffer;
671 TPM2_NV_WRITE_RESPONSE RecvBuffer;
672 UINT32 SendBufferSize;
673 UINT32 RecvBufferSize;
674 UINT8 *Buffer;
675 UINT32 SessionInfoSize;
676 TPM_RC ResponseCode;
677
678 //
679 // Construct command
680 //
681 SendBuffer.Header.tag = SwapBytes16(TPM_ST_SESSIONS);
682 SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_NV_Write);
683
684 SendBuffer.AuthHandle = SwapBytes32 (AuthHandle);
685 SendBuffer.NvIndex = SwapBytes32 (NvIndex);
686
687 //
688 // Add in Auth session
689 //
690 Buffer = (UINT8 *)&SendBuffer.AuthSession;
691
692 // sessionInfoSize
693 SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
694 Buffer += SessionInfoSize;
695 SendBuffer.AuthSessionSize = SwapBytes32(SessionInfoSize);
696
697 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (InData->size));
698 Buffer += sizeof(UINT16);
699 CopyMem (Buffer, InData->buffer, InData->size);
700 Buffer += InData->size;
701 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Offset));
702 Buffer += sizeof(UINT16);
703
704 SendBufferSize = (UINT32) (Buffer - (UINT8 *)&SendBuffer);
705 SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);
706
707 //
708 // send Tpm command
709 //
710 RecvBufferSize = sizeof (RecvBuffer);
711 Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);
712 if (EFI_ERROR (Status)) {
713 goto Done;
714 }
715
716 if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {
717 DEBUG ((EFI_D_ERROR, "Tpm2NvWrite - RecvBufferSize Error - %x\n", RecvBufferSize));
718 Status = EFI_DEVICE_ERROR;
719 goto Done;
720 }
721 ResponseCode = SwapBytes32(RecvBuffer.Header.responseCode);
722 if (ResponseCode != TPM_RC_SUCCESS) {
723 DEBUG ((EFI_D_ERROR, "Tpm2NvWrite - responseCode - %x\n", ResponseCode));
724 }
725 switch (ResponseCode) {
726 case TPM_RC_SUCCESS:
727 // return data
728 break;
729 case TPM_RC_ATTRIBUTES:
730 Status = EFI_UNSUPPORTED;
731 break;
732 case TPM_RC_NV_AUTHORIZATION:
733 Status = EFI_SECURITY_VIOLATION;
734 break;
735 case TPM_RC_NV_LOCKED:
736 Status = EFI_ACCESS_DENIED;
737 break;
738 case TPM_RC_NV_RANGE:
739 Status = EFI_BAD_BUFFER_SIZE;
740 break;
741 case TPM_RC_HANDLE + RC_NV_Write_nvIndex: // TPM_RC_NV_DEFINED:
742 Status = EFI_NOT_FOUND;
743 break;
744 case TPM_RC_HANDLE + RC_NV_Write_authHandle: // TPM_RC_NV_DEFINED:
745 Status = EFI_INVALID_PARAMETER;
746 break;
747 case TPM_RC_VALUE + RC_NV_Write_nvIndex:
748 case TPM_RC_VALUE + RC_NV_Write_authHandle:
749 Status = EFI_INVALID_PARAMETER;
750 break;
751 case TPM_RC_BAD_AUTH + RC_NV_Write_authHandle + TPM_RC_S:
752 Status = EFI_INVALID_PARAMETER;
753 break;
754 case TPM_RC_AUTH_UNAVAILABLE:
755 Status = EFI_INVALID_PARAMETER;
756 break;
757 case TPM_RC_AUTH_FAIL + RC_NV_Write_authHandle + TPM_RC_S:
758 Status = EFI_INVALID_PARAMETER;
759 break;
760 case TPM_RC_ATTRIBUTES + RC_NV_Write_authHandle + TPM_RC_S:
761 Status = EFI_UNSUPPORTED;
762 break;
763 default:
764 Status = EFI_DEVICE_ERROR;
765 break;
766 }
767
768 Done:
769 //
770 // Clear AuthSession Content
771 //
772 ZeroMem (&SendBuffer, sizeof(SendBuffer));
773 ZeroMem (&RecvBuffer, sizeof(RecvBuffer));
774 return Status;
775 }
776
777 /**
778 This command may be used to prevent further reads of the Index until the next TPM2_Startup (TPM_SU_CLEAR).
779
780 @param[in] AuthHandle the handle indicating the source of the authorization value.
781 @param[in] NvIndex The NV Index of the area to lock.
782 @param[in] AuthSession Auth Session context
783
784 @retval EFI_SUCCESS Operation completed successfully.
785 @retval EFI_DEVICE_ERROR The command was unsuccessful.
786 @retval EFI_NOT_FOUND The command was returned successfully, but NvIndex is not found.
787 **/
788 EFI_STATUS
789 EFIAPI
Tpm2NvReadLock(IN TPMI_RH_NV_AUTH AuthHandle,IN TPMI_RH_NV_INDEX NvIndex,IN TPMS_AUTH_COMMAND * AuthSession OPTIONAL)790 Tpm2NvReadLock (
791 IN TPMI_RH_NV_AUTH AuthHandle,
792 IN TPMI_RH_NV_INDEX NvIndex,
793 IN TPMS_AUTH_COMMAND *AuthSession OPTIONAL
794 )
795 {
796 EFI_STATUS Status;
797 TPM2_NV_READLOCK_COMMAND SendBuffer;
798 TPM2_NV_READLOCK_RESPONSE RecvBuffer;
799 UINT32 SendBufferSize;
800 UINT32 RecvBufferSize;
801 UINT8 *Buffer;
802 UINT32 SessionInfoSize;
803 TPM_RC ResponseCode;
804
805 //
806 // Construct command
807 //
808 SendBuffer.Header.tag = SwapBytes16(TPM_ST_SESSIONS);
809 SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_NV_ReadLock);
810
811 SendBuffer.AuthHandle = SwapBytes32 (AuthHandle);
812 SendBuffer.NvIndex = SwapBytes32 (NvIndex);
813
814 //
815 // Add in Auth session
816 //
817 Buffer = (UINT8 *)&SendBuffer.AuthSession;
818
819 // sessionInfoSize
820 SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
821 Buffer += SessionInfoSize;
822 SendBuffer.AuthSessionSize = SwapBytes32(SessionInfoSize);
823
824 SendBufferSize = (UINT32)(Buffer - (UINT8 *)&SendBuffer);
825 SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);
826
827 //
828 // send Tpm command
829 //
830 RecvBufferSize = sizeof (RecvBuffer);
831 Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);
832 if (EFI_ERROR (Status)) {
833 goto Done;
834 }
835
836 if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {
837 DEBUG ((EFI_D_ERROR, "Tpm2NvReadLock - RecvBufferSize Error - %x\n", RecvBufferSize));
838 Status = EFI_DEVICE_ERROR;
839 goto Done;
840 }
841
842 ResponseCode = SwapBytes32(RecvBuffer.Header.responseCode);
843 if (ResponseCode != TPM_RC_SUCCESS) {
844 DEBUG ((EFI_D_ERROR, "Tpm2NvReadLock - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));
845 }
846 switch (ResponseCode) {
847 case TPM_RC_SUCCESS:
848 // return data
849 break;
850 default:
851 Status = EFI_DEVICE_ERROR;
852 break;
853 }
854
855 Done:
856 //
857 // Clear AuthSession Content
858 //
859 ZeroMem (&SendBuffer, sizeof(SendBuffer));
860 ZeroMem (&RecvBuffer, sizeof(RecvBuffer));
861 return Status;
862 }
863
864 /**
865 This command may be used to inhibit further writes of the Index.
866
867 @param[in] AuthHandle the handle indicating the source of the authorization value.
868 @param[in] NvIndex The NV Index of the area to lock.
869 @param[in] AuthSession Auth Session context
870
871 @retval EFI_SUCCESS Operation completed successfully.
872 @retval EFI_DEVICE_ERROR The command was unsuccessful.
873 @retval EFI_NOT_FOUND The command was returned successfully, but NvIndex is not found.
874 **/
875 EFI_STATUS
876 EFIAPI
Tpm2NvWriteLock(IN TPMI_RH_NV_AUTH AuthHandle,IN TPMI_RH_NV_INDEX NvIndex,IN TPMS_AUTH_COMMAND * AuthSession OPTIONAL)877 Tpm2NvWriteLock (
878 IN TPMI_RH_NV_AUTH AuthHandle,
879 IN TPMI_RH_NV_INDEX NvIndex,
880 IN TPMS_AUTH_COMMAND *AuthSession OPTIONAL
881 )
882 {
883 EFI_STATUS Status;
884 TPM2_NV_WRITELOCK_COMMAND SendBuffer;
885 TPM2_NV_WRITELOCK_RESPONSE RecvBuffer;
886 UINT32 SendBufferSize;
887 UINT32 RecvBufferSize;
888 UINT8 *Buffer;
889 UINT32 SessionInfoSize;
890 TPM_RC ResponseCode;
891
892 //
893 // Construct command
894 //
895 SendBuffer.Header.tag = SwapBytes16(TPM_ST_SESSIONS);
896 SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_NV_WriteLock);
897
898 SendBuffer.AuthHandle = SwapBytes32 (AuthHandle);
899 SendBuffer.NvIndex = SwapBytes32 (NvIndex);
900
901 //
902 // Add in Auth session
903 //
904 Buffer = (UINT8 *)&SendBuffer.AuthSession;
905
906 // sessionInfoSize
907 SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
908 Buffer += SessionInfoSize;
909 SendBuffer.AuthSessionSize = SwapBytes32(SessionInfoSize);
910
911 SendBufferSize = (UINT32)(Buffer - (UINT8 *)&SendBuffer);
912 SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);
913
914 //
915 // send Tpm command
916 //
917 RecvBufferSize = sizeof (RecvBuffer);
918 Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);
919 if (EFI_ERROR (Status)) {
920 goto Done;
921 }
922
923 if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {
924 DEBUG ((EFI_D_ERROR, "Tpm2NvWriteLock - RecvBufferSize Error - %x\n", RecvBufferSize));
925 Status = EFI_DEVICE_ERROR;
926 goto Done;
927 }
928
929 ResponseCode = SwapBytes32(RecvBuffer.Header.responseCode);
930 if (ResponseCode != TPM_RC_SUCCESS) {
931 DEBUG ((EFI_D_ERROR, "Tpm2NvWriteLock - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));
932 }
933 switch (ResponseCode) {
934 case TPM_RC_SUCCESS:
935 // return data
936 break;
937 default:
938 Status = EFI_DEVICE_ERROR;
939 break;
940 }
941
942 Done:
943 //
944 // Clear AuthSession Content
945 //
946 ZeroMem (&SendBuffer, sizeof(SendBuffer));
947 ZeroMem (&RecvBuffer, sizeof(RecvBuffer));
948 return Status;
949 }
950
951 /**
952 The command will SET TPMA_NV_WRITELOCKED for all indexes that have their TPMA_NV_GLOBALLOCK attribute SET.
953
954 @param[in] AuthHandle TPM_RH_OWNER or TPM_RH_PLATFORM+{PP}.
955 @param[in] AuthSession Auth Session context
956
957 @retval EFI_SUCCESS Operation completed successfully.
958 @retval EFI_DEVICE_ERROR The command was unsuccessful.
959 @retval EFI_NOT_FOUND The command was returned successfully, but NvIndex is not found.
960 **/
961 EFI_STATUS
962 EFIAPI
Tpm2NvGlobalWriteLock(IN TPMI_RH_PROVISION AuthHandle,IN TPMS_AUTH_COMMAND * AuthSession OPTIONAL)963 Tpm2NvGlobalWriteLock (
964 IN TPMI_RH_PROVISION AuthHandle,
965 IN TPMS_AUTH_COMMAND *AuthSession OPTIONAL
966 )
967 {
968 EFI_STATUS Status;
969 TPM2_NV_GLOBALWRITELOCK_COMMAND SendBuffer;
970 TPM2_NV_GLOBALWRITELOCK_RESPONSE RecvBuffer;
971 UINT32 SendBufferSize;
972 UINT32 RecvBufferSize;
973 UINT8 *Buffer;
974 UINT32 SessionInfoSize;
975 TPM_RC ResponseCode;
976
977 //
978 // Construct command
979 //
980 SendBuffer.Header.tag = SwapBytes16(TPM_ST_SESSIONS);
981 SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_NV_GlobalWriteLock);
982
983 SendBuffer.AuthHandle = SwapBytes32 (AuthHandle);
984
985 //
986 // Add in Auth session
987 //
988 Buffer = (UINT8 *)&SendBuffer.AuthSession;
989
990 // sessionInfoSize
991 SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
992 Buffer += SessionInfoSize;
993 SendBuffer.AuthSessionSize = SwapBytes32(SessionInfoSize);
994
995 SendBufferSize = (UINT32)(Buffer - (UINT8 *)&SendBuffer);
996 SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);
997
998 //
999 // send Tpm command
1000 //
1001 RecvBufferSize = sizeof (RecvBuffer);
1002 Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);
1003 if (EFI_ERROR (Status)) {
1004 goto Done;
1005 }
1006
1007 if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {
1008 DEBUG ((EFI_D_ERROR, "Tpm2NvGlobalWriteLock - RecvBufferSize Error - %x\n", RecvBufferSize));
1009 Status = EFI_DEVICE_ERROR;
1010 goto Done;
1011 }
1012
1013 ResponseCode = SwapBytes32(RecvBuffer.Header.responseCode);
1014 if (ResponseCode != TPM_RC_SUCCESS) {
1015 DEBUG ((EFI_D_ERROR, "Tpm2NvGlobalWriteLock - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));
1016 }
1017 switch (ResponseCode) {
1018 case TPM_RC_SUCCESS:
1019 // return data
1020 break;
1021 default:
1022 Status = EFI_DEVICE_ERROR;
1023 break;
1024 }
1025
1026 Done:
1027 //
1028 // Clear AuthSession Content
1029 //
1030 ZeroMem (&SendBuffer, sizeof(SendBuffer));
1031 ZeroMem (&RecvBuffer, sizeof(RecvBuffer));
1032 return Status;
1033 }
1034