]> git.proxmox.com Git - mirror_edk2.git/blob - SecurityPkg/Library/Tpm2CommandLib/Tpm2Session.c
SecurityPkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / SecurityPkg / Library / Tpm2CommandLib / Tpm2Session.c
1 /** @file
2 Implement TPM2 Session related command.
3
4 Copyright (c) 2014 - 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 typedef struct {
19 TPM2_COMMAND_HEADER Header;
20 TPMI_DH_OBJECT TpmKey;
21 TPMI_DH_ENTITY Bind;
22 TPM2B_NONCE NonceCaller;
23 TPM2B_ENCRYPTED_SECRET Salt;
24 TPM_SE SessionType;
25 TPMT_SYM_DEF Symmetric;
26 TPMI_ALG_HASH AuthHash;
27 } TPM2_START_AUTH_SESSION_COMMAND;
28
29 typedef struct {
30 TPM2_RESPONSE_HEADER Header;
31 TPMI_SH_AUTH_SESSION SessionHandle;
32 TPM2B_NONCE NonceTPM;
33 } TPM2_START_AUTH_SESSION_RESPONSE;
34
35 #pragma pack()
36
37 /**
38 This command is used to start an authorization session using alternative methods of
39 establishing the session key (sessionKey) that is used for authorization and encrypting value.
40
41 @param[in] TpmKey Handle of a loaded decrypt key used to encrypt salt.
42 @param[in] Bind Entity providing the authValue.
43 @param[in] NonceCaller Initial nonceCaller, sets nonce size for the session.
44 @param[in] Salt Value encrypted according to the type of tpmKey.
45 @param[in] SessionType Indicates the type of the session.
46 @param[in] Symmetric The algorithm and key size for parameter encryption.
47 @param[in] AuthHash Hash algorithm to use for the session.
48 @param[out] SessionHandle Handle for the newly created session.
49 @param[out] NonceTPM The initial nonce from the TPM, used in the computation of the sessionKey.
50
51 @retval EFI_SUCCESS Operation completed successfully.
52 @retval EFI_DEVICE_ERROR The command was unsuccessful.
53 **/
54 EFI_STATUS
55 EFIAPI
56 Tpm2StartAuthSession (
57 IN TPMI_DH_OBJECT TpmKey,
58 IN TPMI_DH_ENTITY Bind,
59 IN TPM2B_NONCE *NonceCaller,
60 IN TPM2B_ENCRYPTED_SECRET *Salt,
61 IN TPM_SE SessionType,
62 IN TPMT_SYM_DEF *Symmetric,
63 IN TPMI_ALG_HASH AuthHash,
64 OUT TPMI_SH_AUTH_SESSION *SessionHandle,
65 OUT TPM2B_NONCE *NonceTPM
66 )
67 {
68 EFI_STATUS Status;
69 TPM2_START_AUTH_SESSION_COMMAND SendBuffer;
70 TPM2_START_AUTH_SESSION_RESPONSE RecvBuffer;
71 UINT32 SendBufferSize;
72 UINT32 RecvBufferSize;
73 UINT8 *Buffer;
74
75 //
76 // Construct command
77 //
78 SendBuffer.Header.tag = SwapBytes16(TPM_ST_NO_SESSIONS);
79 SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_StartAuthSession);
80
81 SendBuffer.TpmKey = SwapBytes32 (TpmKey);
82 SendBuffer.Bind = SwapBytes32 (Bind);
83 Buffer = (UINT8 *)&SendBuffer.NonceCaller;
84
85 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (NonceCaller->size));
86 Buffer += sizeof(UINT16);
87 CopyMem (Buffer, NonceCaller->buffer, NonceCaller->size);
88 Buffer += NonceCaller->size;
89
90 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Salt->size));
91 Buffer += sizeof(UINT16);
92 CopyMem (Buffer, Salt->secret, Salt->size);
93 Buffer += Salt->size;
94
95 *(TPM_SE *)Buffer = SessionType;
96 Buffer++;
97
98 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Symmetric->algorithm));
99 Buffer += sizeof(UINT16);
100 switch (Symmetric->algorithm) {
101 case TPM_ALG_NULL:
102 break;
103 case TPM_ALG_AES:
104 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Symmetric->keyBits.aes));
105 Buffer += sizeof(UINT16);
106 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Symmetric->mode.aes));
107 Buffer += sizeof(UINT16);
108 break;
109 case TPM_ALG_SM4:
110 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Symmetric->keyBits.SM4));
111 Buffer += sizeof(UINT16);
112 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Symmetric->mode.SM4));
113 Buffer += sizeof(UINT16);
114 break;
115 case TPM_ALG_SYMCIPHER:
116 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Symmetric->keyBits.sym));
117 Buffer += sizeof(UINT16);
118 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Symmetric->mode.sym));
119 Buffer += sizeof(UINT16);
120 break;
121 case TPM_ALG_XOR:
122 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Symmetric->keyBits.xor));
123 Buffer += sizeof(UINT16);
124 break;
125 default:
126 ASSERT (FALSE);
127 DEBUG ((EFI_D_ERROR, "Tpm2StartAuthSession - Symmetric->algorithm - %x\n", Symmetric->algorithm));
128 return EFI_UNSUPPORTED;
129 }
130
131 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (AuthHash));
132 Buffer += sizeof(UINT16);
133
134 SendBufferSize = (UINT32) ((UINTN)Buffer - (UINTN)&SendBuffer);
135 SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);
136
137 //
138 // send Tpm command
139 //
140 RecvBufferSize = sizeof (RecvBuffer);
141 Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);
142 if (EFI_ERROR (Status)) {
143 return Status;
144 }
145
146 if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {
147 DEBUG ((EFI_D_ERROR, "Tpm2StartAuthSession - RecvBufferSize Error - %x\n", RecvBufferSize));
148 return EFI_DEVICE_ERROR;
149 }
150 if (SwapBytes32(RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) {
151 DEBUG ((EFI_D_ERROR, "Tpm2StartAuthSession - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));
152 return EFI_DEVICE_ERROR;
153 }
154
155 //
156 // Return the response
157 //
158 *SessionHandle = SwapBytes32 (RecvBuffer.SessionHandle);
159 NonceTPM->size = SwapBytes16 (RecvBuffer.NonceTPM.size);
160 if (NonceTPM->size > sizeof(TPMU_HA)) {
161 DEBUG ((DEBUG_ERROR, "Tpm2StartAuthSession - NonceTPM->size error %x\n", NonceTPM->size));
162 return EFI_DEVICE_ERROR;
163 }
164
165 CopyMem (NonceTPM->buffer, &RecvBuffer.NonceTPM.buffer, NonceTPM->size);
166
167 return EFI_SUCCESS;
168 }