xref: /aosp_15_r20/external/tpm2-tss/test/integration/sapi-session-util.c (revision 758e9fba6fc9adbf15340f70c73baee7b168b1c9)
1*758e9fbaSOystein Eftevaag /* SPDX-License-Identifier: BSD-2-Clause */
2*758e9fbaSOystein Eftevaag /***********************************************************************
3*758e9fbaSOystein Eftevaag  * Copyright (c) 2017-2018, Intel Corporation
4*758e9fbaSOystein Eftevaag  *
5*758e9fbaSOystein Eftevaag  * All rights reserved.
6*758e9fbaSOystein Eftevaag  ***********************************************************************/
7*758e9fbaSOystein Eftevaag #ifdef HAVE_CONFIG_H
8*758e9fbaSOystein Eftevaag #include <config.h>
9*758e9fbaSOystein Eftevaag #endif
10*758e9fbaSOystein Eftevaag 
11*758e9fbaSOystein Eftevaag #include <inttypes.h>
12*758e9fbaSOystein Eftevaag 
13*758e9fbaSOystein Eftevaag #include "session-util.h"
14*758e9fbaSOystein Eftevaag #include "sapi-util.h"
15*758e9fbaSOystein Eftevaag #include "context-util.h"
16*758e9fbaSOystein Eftevaag #include "util/tss2_endian.h"
17*758e9fbaSOystein Eftevaag #define LOGMODULE test
18*758e9fbaSOystein Eftevaag #include "util/log.h"
19*758e9fbaSOystein Eftevaag 
20*758e9fbaSOystein Eftevaag static SESSION *sessions = NULL;
21*758e9fbaSOystein Eftevaag 
22*758e9fbaSOystein Eftevaag SESSION *
get_session(TPMI_SH_AUTH_SESSION hndl)23*758e9fbaSOystein Eftevaag get_session(TPMI_SH_AUTH_SESSION hndl)
24*758e9fbaSOystein Eftevaag {
25*758e9fbaSOystein Eftevaag     SESSION *s;
26*758e9fbaSOystein Eftevaag 
27*758e9fbaSOystein Eftevaag     HASH_FIND_INT(sessions, &hndl, s);
28*758e9fbaSOystein Eftevaag     return s;
29*758e9fbaSOystein Eftevaag }
30*758e9fbaSOystein Eftevaag 
31*758e9fbaSOystein Eftevaag static TSS2_RC
start_auth_session(SESSION * session,TSS2_TCTI_CONTEXT * tctiContext)32*758e9fbaSOystein Eftevaag start_auth_session(
33*758e9fbaSOystein Eftevaag     SESSION *session,
34*758e9fbaSOystein Eftevaag     TSS2_TCTI_CONTEXT *tctiContext)
35*758e9fbaSOystein Eftevaag {
36*758e9fbaSOystein Eftevaag     TSS2_RC rval;
37*758e9fbaSOystein Eftevaag     TPM2B_ENCRYPTED_SECRET key;
38*758e9fbaSOystein Eftevaag     char label[] = "ATH";
39*758e9fbaSOystein Eftevaag     TSS2_SYS_CONTEXT *tmp_context;
40*758e9fbaSOystein Eftevaag     UINT16 bytes;
41*758e9fbaSOystein Eftevaag 
42*758e9fbaSOystein Eftevaag     key.size = 0;
43*758e9fbaSOystein Eftevaag 
44*758e9fbaSOystein Eftevaag     tmp_context = sapi_init_from_tcti_ctx(tctiContext);
45*758e9fbaSOystein Eftevaag     if (tmp_context == NULL)
46*758e9fbaSOystein Eftevaag         return TSS2_SYS_RC_GENERAL_FAILURE;
47*758e9fbaSOystein Eftevaag 
48*758e9fbaSOystein Eftevaag     if (session->nonceOlder.size == 0)
49*758e9fbaSOystein Eftevaag         session->nonceOlder.size = GetDigestSize(session->authHash);
50*758e9fbaSOystein Eftevaag 
51*758e9fbaSOystein Eftevaag     memset(session->nonceOlder.buffer, '\0', session->nonceOlder.size);
52*758e9fbaSOystein Eftevaag     session->nonceNewer.size = session->nonceOlder.size;
53*758e9fbaSOystein Eftevaag     session->nonceTpmDecrypt.size = 0;
54*758e9fbaSOystein Eftevaag     session->nonceTpmEncrypt.size = 0;
55*758e9fbaSOystein Eftevaag 
56*758e9fbaSOystein Eftevaag     rval = Tss2_Sys_StartAuthSession(
57*758e9fbaSOystein Eftevaag             tmp_context, session->tpmKey, session->bind, 0,
58*758e9fbaSOystein Eftevaag             &session->nonceOlder, &session->encryptedSalt,
59*758e9fbaSOystein Eftevaag             session->sessionType, &session->symmetric,
60*758e9fbaSOystein Eftevaag             session->authHash, &session->sessionHandle,
61*758e9fbaSOystein Eftevaag             &session->nonceNewer, 0);
62*758e9fbaSOystein Eftevaag     if (rval != TPM2_RC_SUCCESS)
63*758e9fbaSOystein Eftevaag         goto out;
64*758e9fbaSOystein Eftevaag 
65*758e9fbaSOystein Eftevaag     if (session->tpmKey == TPM2_RH_NULL)
66*758e9fbaSOystein Eftevaag         session->salt.size = 0;
67*758e9fbaSOystein Eftevaag 
68*758e9fbaSOystein Eftevaag     if (session->bind == TPM2_RH_NULL)
69*758e9fbaSOystein Eftevaag         session->authValueBind.size = 0;
70*758e9fbaSOystein Eftevaag 
71*758e9fbaSOystein Eftevaag     session->sessionKey.size = 0;
72*758e9fbaSOystein Eftevaag     if (session->tpmKey == TPM2_RH_NULL && session->bind == TPM2_RH_NULL)
73*758e9fbaSOystein Eftevaag         goto out;
74*758e9fbaSOystein Eftevaag 
75*758e9fbaSOystein Eftevaag     /* Generate the key used as input to the KDF. */
76*758e9fbaSOystein Eftevaag     rval = ConcatSizedByteBuffer((TPM2B_MAX_BUFFER *)&key,
77*758e9fbaSOystein Eftevaag             (TPM2B *)&session->authValueBind);
78*758e9fbaSOystein Eftevaag     if (rval != TPM2_RC_SUCCESS) {
79*758e9fbaSOystein Eftevaag         Tss2_Sys_FlushContext(tmp_context, session->sessionHandle);
80*758e9fbaSOystein Eftevaag         goto out;
81*758e9fbaSOystein Eftevaag     }
82*758e9fbaSOystein Eftevaag 
83*758e9fbaSOystein Eftevaag     rval = ConcatSizedByteBuffer((TPM2B_MAX_BUFFER *)&key,
84*758e9fbaSOystein Eftevaag             (TPM2B *)&session->salt);
85*758e9fbaSOystein Eftevaag     if (rval != TPM2_RC_SUCCESS) {
86*758e9fbaSOystein Eftevaag         Tss2_Sys_FlushContext(tmp_context, session->sessionHandle);
87*758e9fbaSOystein Eftevaag         goto out;
88*758e9fbaSOystein Eftevaag     }
89*758e9fbaSOystein Eftevaag 
90*758e9fbaSOystein Eftevaag     bytes = GetDigestSize(session->authHash) * 8;
91*758e9fbaSOystein Eftevaag 
92*758e9fbaSOystein Eftevaag     rval = KDFa(session->authHash, (TPM2B *)&key, label,
93*758e9fbaSOystein Eftevaag                 (TPM2B *)&session->nonceNewer,
94*758e9fbaSOystein Eftevaag                 (TPM2B *)&session->nonceOlder,
95*758e9fbaSOystein Eftevaag                 bytes, (TPM2B_MAX_BUFFER *)&session->sessionKey);
96*758e9fbaSOystein Eftevaag out:
97*758e9fbaSOystein Eftevaag     sapi_teardown(tmp_context);
98*758e9fbaSOystein Eftevaag     return rval;
99*758e9fbaSOystein Eftevaag }
100*758e9fbaSOystein Eftevaag 
101*758e9fbaSOystein Eftevaag static TSS2_RC
compute_session_auth(TSS2_SYS_CONTEXT * sysContext,SESSION * session,TPMS_AUTH_COMMAND * pSessionDataIn,bool command,TPM2_HANDLE handle1,TPM2_HANDLE handle2,TPM2_HANDLE handle3,TPM2B_MAX_BUFFER * hmacKey)102*758e9fbaSOystein Eftevaag compute_session_auth(
103*758e9fbaSOystein Eftevaag     TSS2_SYS_CONTEXT *sysContext,
104*758e9fbaSOystein Eftevaag     SESSION *session,
105*758e9fbaSOystein Eftevaag     TPMS_AUTH_COMMAND *pSessionDataIn,
106*758e9fbaSOystein Eftevaag     bool command,
107*758e9fbaSOystein Eftevaag     TPM2_HANDLE handle1,
108*758e9fbaSOystein Eftevaag     TPM2_HANDLE handle2,
109*758e9fbaSOystein Eftevaag     TPM2_HANDLE handle3,
110*758e9fbaSOystein Eftevaag     TPM2B_MAX_BUFFER *hmacKey)
111*758e9fbaSOystein Eftevaag {
112*758e9fbaSOystein Eftevaag     TPM2B_DIGEST *buffer_list[7];
113*758e9fbaSOystein Eftevaag     TPM2B_DIGEST pHash = TPM2B_DIGEST_INIT;
114*758e9fbaSOystein Eftevaag     TPM2B sessionAttributesByteBuffer = {
115*758e9fbaSOystein Eftevaag         .size = 1,
116*758e9fbaSOystein Eftevaag         .buffer = pSessionDataIn->sessionAttributes
117*758e9fbaSOystein Eftevaag     };
118*758e9fbaSOystein Eftevaag     UINT16 i;
119*758e9fbaSOystein Eftevaag     TSS2_RC rval;
120*758e9fbaSOystein Eftevaag     TPM2_CC cmdCode;
121*758e9fbaSOystein Eftevaag 
122*758e9fbaSOystein Eftevaag     rval = tpm_calc_phash(sysContext, handle1, handle2, handle3,
123*758e9fbaSOystein Eftevaag                         session->authHash, command, &pHash);
124*758e9fbaSOystein Eftevaag     if (rval != TPM2_RC_SUCCESS)
125*758e9fbaSOystein Eftevaag         return rval;
126*758e9fbaSOystein Eftevaag 
127*758e9fbaSOystein Eftevaag     rval = Tss2_Sys_GetCommandCode(sysContext, (UINT8 *)&cmdCode);
128*758e9fbaSOystein Eftevaag     if (rval != TPM2_RC_SUCCESS)
129*758e9fbaSOystein Eftevaag         return rval;
130*758e9fbaSOystein Eftevaag 
131*758e9fbaSOystein Eftevaag     /* cmdCode comes back as BigEndian; not suited for comparisons below. */
132*758e9fbaSOystein Eftevaag     cmdCode = BE_TO_HOST_32(cmdCode);
133*758e9fbaSOystein Eftevaag     LOGBLOB_DEBUG(hmacKey->buffer, hmacKey->size, "hmacKey=");
134*758e9fbaSOystein Eftevaag 
135*758e9fbaSOystein Eftevaag     i = 0;
136*758e9fbaSOystein Eftevaag     buffer_list[i++] = (TPM2B_DIGEST *)&pHash;
137*758e9fbaSOystein Eftevaag     buffer_list[i++] = (TPM2B_DIGEST *)&session->nonceNewer;
138*758e9fbaSOystein Eftevaag     buffer_list[i++] = (TPM2B_DIGEST *)&session->nonceOlder;
139*758e9fbaSOystein Eftevaag     buffer_list[i++] = (TPM2B_DIGEST *)&session->nonceTpmDecrypt;
140*758e9fbaSOystein Eftevaag     buffer_list[i++] = (TPM2B_DIGEST *)&session->nonceTpmEncrypt;
141*758e9fbaSOystein Eftevaag     buffer_list[i++] = (TPM2B_DIGEST *)&sessionAttributesByteBuffer;
142*758e9fbaSOystein Eftevaag     buffer_list[i++] = 0;
143*758e9fbaSOystein Eftevaag 
144*758e9fbaSOystein Eftevaag     for (int j = 0; buffer_list[j] != 0; j++) {
145*758e9fbaSOystein Eftevaag             LOGBLOB_DEBUG(&buffer_list[j]->buffer[0],
146*758e9fbaSOystein Eftevaag                     buffer_list[j]->size, "bufferlist[%d]:", j);
147*758e9fbaSOystein Eftevaag             ;
148*758e9fbaSOystein Eftevaag     }
149*758e9fbaSOystein Eftevaag 
150*758e9fbaSOystein Eftevaag     rval = hmac(session->authHash, hmacKey->buffer,
151*758e9fbaSOystein Eftevaag             hmacKey->size, buffer_list,
152*758e9fbaSOystein Eftevaag             (TPM2B_DIGEST *)&pSessionDataIn->hmac);
153*758e9fbaSOystein Eftevaag 
154*758e9fbaSOystein Eftevaag     if (rval != TPM2_RC_SUCCESS) {
155*758e9fbaSOystein Eftevaag         LOGBLOB_ERROR(pSessionDataIn->hmac.buffer,
156*758e9fbaSOystein Eftevaag                       pSessionDataIn->hmac.size,
157*758e9fbaSOystein Eftevaag                       "HMAC Failed rval = %d !!!", rval);
158*758e9fbaSOystein Eftevaag         return rval;
159*758e9fbaSOystein Eftevaag     }
160*758e9fbaSOystein Eftevaag     return rval;
161*758e9fbaSOystein Eftevaag }
162*758e9fbaSOystein Eftevaag 
163*758e9fbaSOystein Eftevaag TSS2_RC
compute_command_hmac(TSS2_SYS_CONTEXT * sysContext,TPM2_HANDLE handle1,TPM2_HANDLE handle2,TPM2_HANDLE handle3,TSS2L_SYS_AUTH_COMMAND * pSessionsDataIn)164*758e9fbaSOystein Eftevaag compute_command_hmac(
165*758e9fbaSOystein Eftevaag     TSS2_SYS_CONTEXT *sysContext,
166*758e9fbaSOystein Eftevaag     TPM2_HANDLE handle1,
167*758e9fbaSOystein Eftevaag     TPM2_HANDLE handle2,
168*758e9fbaSOystein Eftevaag     TPM2_HANDLE handle3,
169*758e9fbaSOystein Eftevaag     TSS2L_SYS_AUTH_COMMAND *pSessionsDataIn)
170*758e9fbaSOystein Eftevaag {
171*758e9fbaSOystein Eftevaag     TPM2_HANDLE handles[3] = {handle1, handle2, handle3};
172*758e9fbaSOystein Eftevaag     ENTITY *entity;
173*758e9fbaSOystein Eftevaag     SESSION *session;
174*758e9fbaSOystein Eftevaag     TPM2B_MAX_BUFFER hmac_key;
175*758e9fbaSOystein Eftevaag     TSS2_RC rval = TPM2_RC_SUCCESS;
176*758e9fbaSOystein Eftevaag     unsigned int i;
177*758e9fbaSOystein Eftevaag     unsigned int count = pSessionsDataIn->count;
178*758e9fbaSOystein Eftevaag 
179*758e9fbaSOystein Eftevaag     if (count > 3) {
180*758e9fbaSOystein Eftevaag         LOG_ERROR("Bad value for session count: %" PRIu16, count);
181*758e9fbaSOystein Eftevaag         return TSS2_SYS_RC_GENERAL_FAILURE;
182*758e9fbaSOystein Eftevaag     }
183*758e9fbaSOystein Eftevaag 
184*758e9fbaSOystein Eftevaag     for (i = 0; i < count; i++) {
185*758e9fbaSOystein Eftevaag         if (handles[i] == TPM2_RH_NULL)
186*758e9fbaSOystein Eftevaag             break;
187*758e9fbaSOystein Eftevaag 
188*758e9fbaSOystein Eftevaag         entity = GetEntity(handles[i]);
189*758e9fbaSOystein Eftevaag         if (!entity)
190*758e9fbaSOystein Eftevaag             return TSS2_SYS_RC_GENERAL_FAILURE;
191*758e9fbaSOystein Eftevaag 
192*758e9fbaSOystein Eftevaag         session = get_session(pSessionsDataIn->auths[i].sessionHandle);
193*758e9fbaSOystein Eftevaag         if (!session)
194*758e9fbaSOystein Eftevaag             return TPM2_RC_SUCCESS;
195*758e9fbaSOystein Eftevaag 
196*758e9fbaSOystein Eftevaag         CopySizedByteBuffer((TPM2B *)&hmac_key, (TPM2B *)&session->sessionKey);
197*758e9fbaSOystein Eftevaag 
198*758e9fbaSOystein Eftevaag         if (handles[i] != session->bind || handles[i] == TPM2_RH_NULL)
199*758e9fbaSOystein Eftevaag             ConcatSizedByteBuffer(&hmac_key, (TPM2B *)&entity->entityAuth);
200*758e9fbaSOystein Eftevaag 
201*758e9fbaSOystein Eftevaag         rval = compute_session_auth(sysContext,
202*758e9fbaSOystein Eftevaag                 session,
203*758e9fbaSOystein Eftevaag                 &pSessionsDataIn->auths[i],
204*758e9fbaSOystein Eftevaag                 true,
205*758e9fbaSOystein Eftevaag                 handle1,
206*758e9fbaSOystein Eftevaag                 handle2,
207*758e9fbaSOystein Eftevaag                 handle3,
208*758e9fbaSOystein Eftevaag                 &hmac_key);
209*758e9fbaSOystein Eftevaag         if (rval != TPM2_RC_SUCCESS)
210*758e9fbaSOystein Eftevaag             break;
211*758e9fbaSOystein Eftevaag     }
212*758e9fbaSOystein Eftevaag     return rval;
213*758e9fbaSOystein Eftevaag }
214*758e9fbaSOystein Eftevaag 
check_response_hmac(TSS2_SYS_CONTEXT * sysContext,TSS2L_SYS_AUTH_COMMAND * pSessionsDataIn,TPM2_HANDLE handle1,TPM2_HANDLE handle2,TPM2_HANDLE handle3,TSS2L_SYS_AUTH_RESPONSE * pSessionsDataOut)215*758e9fbaSOystein Eftevaag TSS2_RC check_response_hmac(
216*758e9fbaSOystein Eftevaag         TSS2_SYS_CONTEXT *sysContext,
217*758e9fbaSOystein Eftevaag         TSS2L_SYS_AUTH_COMMAND *pSessionsDataIn,
218*758e9fbaSOystein Eftevaag         TPM2_HANDLE handle1,
219*758e9fbaSOystein Eftevaag         TPM2_HANDLE handle2,
220*758e9fbaSOystein Eftevaag         TPM2_HANDLE handle3,
221*758e9fbaSOystein Eftevaag         TSS2L_SYS_AUTH_RESPONSE *pSessionsDataOut)
222*758e9fbaSOystein Eftevaag {
223*758e9fbaSOystein Eftevaag     TPM2_HANDLE handles[3] = {handle1, handle2, handle3};
224*758e9fbaSOystein Eftevaag     ENTITY *entity;
225*758e9fbaSOystein Eftevaag     SESSION *session;
226*758e9fbaSOystein Eftevaag     TPM2B_MAX_BUFFER hmac_key;
227*758e9fbaSOystein Eftevaag     TSS2_RC rval = TPM2_RC_SUCCESS;
228*758e9fbaSOystein Eftevaag     unsigned int i;
229*758e9fbaSOystein Eftevaag     unsigned int count = pSessionsDataIn->count;
230*758e9fbaSOystein Eftevaag 
231*758e9fbaSOystein Eftevaag     if (count > 3) {
232*758e9fbaSOystein Eftevaag         LOG_ERROR("Bad value for session count: %" PRIu16, count);
233*758e9fbaSOystein Eftevaag         return TSS2_SYS_RC_GENERAL_FAILURE;
234*758e9fbaSOystein Eftevaag     }
235*758e9fbaSOystein Eftevaag 
236*758e9fbaSOystein Eftevaag     for (i = 0; i < count; i++) {
237*758e9fbaSOystein Eftevaag         if (handles[i] == TPM2_RH_NULL)
238*758e9fbaSOystein Eftevaag             break;
239*758e9fbaSOystein Eftevaag 
240*758e9fbaSOystein Eftevaag         entity = GetEntity(handles[i]);
241*758e9fbaSOystein Eftevaag         if (!entity)
242*758e9fbaSOystein Eftevaag             return TSS2_SYS_RC_GENERAL_FAILURE;
243*758e9fbaSOystein Eftevaag 
244*758e9fbaSOystein Eftevaag         session = get_session(pSessionsDataIn->auths[i].sessionHandle);
245*758e9fbaSOystein Eftevaag         if (!session)
246*758e9fbaSOystein Eftevaag             return TPM2_RC_SUCCESS;
247*758e9fbaSOystein Eftevaag 
248*758e9fbaSOystein Eftevaag         CopySizedByteBuffer((TPM2B *)&hmac_key, (TPM2B *)&session->sessionKey);
249*758e9fbaSOystein Eftevaag 
250*758e9fbaSOystein Eftevaag         if (handles[i] != session->bind)
251*758e9fbaSOystein Eftevaag             ConcatSizedByteBuffer(&hmac_key, (TPM2B *)&entity->entityAuth);
252*758e9fbaSOystein Eftevaag 
253*758e9fbaSOystein Eftevaag         rval = compute_session_auth(sysContext,
254*758e9fbaSOystein Eftevaag                     session,
255*758e9fbaSOystein Eftevaag                     &pSessionsDataIn->auths[i],
256*758e9fbaSOystein Eftevaag                     false,
257*758e9fbaSOystein Eftevaag                     handle1,
258*758e9fbaSOystein Eftevaag                     handle2,
259*758e9fbaSOystein Eftevaag                     handle3,
260*758e9fbaSOystein Eftevaag                     &hmac_key);
261*758e9fbaSOystein Eftevaag 
262*758e9fbaSOystein Eftevaag         if (rval != TPM2_RC_SUCCESS)
263*758e9fbaSOystein Eftevaag             return rval;
264*758e9fbaSOystein Eftevaag 
265*758e9fbaSOystein Eftevaag         rval = CompareSizedByteBuffer((TPM2B *)&pSessionsDataIn->auths[i].hmac,
266*758e9fbaSOystein Eftevaag                                       (TPM2B *)&pSessionsDataOut->auths[i].hmac);
267*758e9fbaSOystein Eftevaag         if (rval != TPM2_RC_SUCCESS)
268*758e9fbaSOystein Eftevaag             return TSS2_SYS_RC_GENERAL_FAILURE;
269*758e9fbaSOystein Eftevaag     }
270*758e9fbaSOystein Eftevaag     return rval;
271*758e9fbaSOystein Eftevaag }
272*758e9fbaSOystein Eftevaag 
create_auth_session(SESSION ** psession,TPMI_DH_OBJECT tpmKey,TPM2B_MAX_BUFFER * salt,TPMI_DH_ENTITY bind,TPM2B_AUTH * bindAuth,TPM2B_NONCE * nonceCaller,TPM2B_ENCRYPTED_SECRET * encryptedSalt,TPM2_SE sessionType,TPMT_SYM_DEF * symmetric,TPMI_ALG_HASH algId,TSS2_TCTI_CONTEXT * tctiContext)273*758e9fbaSOystein Eftevaag TSS2_RC create_auth_session(
274*758e9fbaSOystein Eftevaag     SESSION **psession,
275*758e9fbaSOystein Eftevaag     TPMI_DH_OBJECT tpmKey,
276*758e9fbaSOystein Eftevaag     TPM2B_MAX_BUFFER *salt,
277*758e9fbaSOystein Eftevaag     TPMI_DH_ENTITY bind,
278*758e9fbaSOystein Eftevaag     TPM2B_AUTH *bindAuth,
279*758e9fbaSOystein Eftevaag     TPM2B_NONCE *nonceCaller,
280*758e9fbaSOystein Eftevaag     TPM2B_ENCRYPTED_SECRET *encryptedSalt,
281*758e9fbaSOystein Eftevaag     TPM2_SE sessionType,
282*758e9fbaSOystein Eftevaag     TPMT_SYM_DEF *symmetric,
283*758e9fbaSOystein Eftevaag     TPMI_ALG_HASH algId,
284*758e9fbaSOystein Eftevaag     TSS2_TCTI_CONTEXT *tctiContext)
285*758e9fbaSOystein Eftevaag {
286*758e9fbaSOystein Eftevaag     TSS2_RC rval;
287*758e9fbaSOystein Eftevaag     SESSION *session, *tmp;
288*758e9fbaSOystein Eftevaag 
289*758e9fbaSOystein Eftevaag     if (psession == NULL)
290*758e9fbaSOystein Eftevaag         return TSS2_SYS_RC_BAD_REFERENCE;
291*758e9fbaSOystein Eftevaag 
292*758e9fbaSOystein Eftevaag     session = calloc(1, sizeof(SESSION));
293*758e9fbaSOystein Eftevaag 
294*758e9fbaSOystein Eftevaag     if (!session)
295*758e9fbaSOystein Eftevaag         return TSS2_SYS_RC_GENERAL_FAILURE;
296*758e9fbaSOystein Eftevaag 
297*758e9fbaSOystein Eftevaag     session->bind = bind;
298*758e9fbaSOystein Eftevaag     session->tpmKey = tpmKey;
299*758e9fbaSOystein Eftevaag     CopySizedByteBuffer((TPM2B *)&session->nonceOlder, (TPM2B *)nonceCaller);
300*758e9fbaSOystein Eftevaag     CopySizedByteBuffer((TPM2B *)&session->encryptedSalt, (TPM2B *)encryptedSalt);
301*758e9fbaSOystein Eftevaag     session->sessionType = sessionType;
302*758e9fbaSOystein Eftevaag     session->symmetric.algorithm = symmetric->algorithm;
303*758e9fbaSOystein Eftevaag     session->symmetric.keyBits.sym = symmetric->keyBits.sym;
304*758e9fbaSOystein Eftevaag     session->symmetric.mode.sym = symmetric->mode.sym;
305*758e9fbaSOystein Eftevaag     session->authHash = algId;
306*758e9fbaSOystein Eftevaag     if (bindAuth != NULL)
307*758e9fbaSOystein Eftevaag         CopySizedByteBuffer((TPM2B *)&session->authValueBind, (TPM2B *)bindAuth);
308*758e9fbaSOystein Eftevaag 
309*758e9fbaSOystein Eftevaag     if (session->tpmKey != TPM2_RH_NULL)
310*758e9fbaSOystein Eftevaag         CopySizedByteBuffer((TPM2B *)&session->salt, (TPM2B *)salt);
311*758e9fbaSOystein Eftevaag 
312*758e9fbaSOystein Eftevaag     rval = start_auth_session(session, tctiContext);
313*758e9fbaSOystein Eftevaag     if (rval != TSS2_RC_SUCCESS) {
314*758e9fbaSOystein Eftevaag         free(session);
315*758e9fbaSOystein Eftevaag         return rval;
316*758e9fbaSOystein Eftevaag     }
317*758e9fbaSOystein Eftevaag     /* Make sure this session handle is not already in the table */
318*758e9fbaSOystein Eftevaag     HASH_FIND_INT(sessions, &session->sessionHandle, tmp);
319*758e9fbaSOystein Eftevaag     if (tmp)
320*758e9fbaSOystein Eftevaag         HASH_DEL(sessions, tmp);
321*758e9fbaSOystein Eftevaag 
322*758e9fbaSOystein Eftevaag     HASH_ADD_INT(sessions, sessionHandle, session);
323*758e9fbaSOystein Eftevaag     *psession = session;
324*758e9fbaSOystein Eftevaag     return TSS2_RC_SUCCESS;
325*758e9fbaSOystein Eftevaag }
326*758e9fbaSOystein Eftevaag 
end_auth_session(SESSION * session)327*758e9fbaSOystein Eftevaag void end_auth_session(SESSION *session)
328*758e9fbaSOystein Eftevaag {
329*758e9fbaSOystein Eftevaag     HASH_DEL(sessions, session);
330*758e9fbaSOystein Eftevaag     free(session);
331*758e9fbaSOystein Eftevaag }
332*758e9fbaSOystein Eftevaag 
roll_nonces(SESSION * session,TPM2B_NONCE * new_nonce)333*758e9fbaSOystein Eftevaag void roll_nonces(SESSION *session, TPM2B_NONCE *new_nonce)
334*758e9fbaSOystein Eftevaag {
335*758e9fbaSOystein Eftevaag     session->nonceOlder = session->nonceNewer;
336*758e9fbaSOystein Eftevaag     session->nonceNewer = *new_nonce;
337*758e9fbaSOystein Eftevaag }
338*758e9fbaSOystein Eftevaag 
339*758e9fbaSOystein Eftevaag TSS2_RC
tpm_calc_phash(TSS2_SYS_CONTEXT * sysContext,TPM2_HANDLE handle1,TPM2_HANDLE handle2,TPM2_HANDLE handle3,TPMI_ALG_HASH authHash,bool command,TPM2B_DIGEST * pHash)340*758e9fbaSOystein Eftevaag tpm_calc_phash(
341*758e9fbaSOystein Eftevaag     TSS2_SYS_CONTEXT *sysContext,
342*758e9fbaSOystein Eftevaag     TPM2_HANDLE handle1,
343*758e9fbaSOystein Eftevaag     TPM2_HANDLE handle2,
344*758e9fbaSOystein Eftevaag     TPM2_HANDLE handle3,
345*758e9fbaSOystein Eftevaag     TPMI_ALG_HASH authHash,
346*758e9fbaSOystein Eftevaag     bool command,
347*758e9fbaSOystein Eftevaag     TPM2B_DIGEST *pHash)
348*758e9fbaSOystein Eftevaag {
349*758e9fbaSOystein Eftevaag     TSS2_RC rval = TPM2_RC_SUCCESS;
350*758e9fbaSOystein Eftevaag     TSS2_TCTI_CONTEXT *tcti_context;
351*758e9fbaSOystein Eftevaag     UINT32 i;
352*758e9fbaSOystein Eftevaag     TPM2B_NAME name1, name2, name3;
353*758e9fbaSOystein Eftevaag     TPM2B_MAX_BUFFER hashInput;
354*758e9fbaSOystein Eftevaag     UINT8 *hashInputPtr;
355*758e9fbaSOystein Eftevaag     size_t parametersSize;
356*758e9fbaSOystein Eftevaag     const uint8_t *startParams;
357*758e9fbaSOystein Eftevaag     TPM2_CC cmdCode;
358*758e9fbaSOystein Eftevaag 
359*758e9fbaSOystein Eftevaag     name1.size = 0;
360*758e9fbaSOystein Eftevaag     name2.size = 0;
361*758e9fbaSOystein Eftevaag     name3.size = 0;
362*758e9fbaSOystein Eftevaag     hashInput.size = 0;
363*758e9fbaSOystein Eftevaag 
364*758e9fbaSOystein Eftevaag     rval = Tss2_Sys_GetTctiContext(sysContext, &tcti_context);
365*758e9fbaSOystein Eftevaag     if (rval != TPM2_RC_SUCCESS)
366*758e9fbaSOystein Eftevaag         return rval;
367*758e9fbaSOystein Eftevaag 
368*758e9fbaSOystein Eftevaag     if (command) {
369*758e9fbaSOystein Eftevaag         rval = tpm_handle_to_name(tcti_context, handle1, &name1);
370*758e9fbaSOystein Eftevaag         if (rval != TPM2_RC_SUCCESS)
371*758e9fbaSOystein Eftevaag                 return rval;
372*758e9fbaSOystein Eftevaag 
373*758e9fbaSOystein Eftevaag         rval = tpm_handle_to_name(tcti_context, handle2, &name2);
374*758e9fbaSOystein Eftevaag         if (rval != TPM2_RC_SUCCESS)
375*758e9fbaSOystein Eftevaag             return rval;
376*758e9fbaSOystein Eftevaag 
377*758e9fbaSOystein Eftevaag         rval = tpm_handle_to_name(tcti_context, handle3, &name3);
378*758e9fbaSOystein Eftevaag         if (rval != TPM2_RC_SUCCESS)
379*758e9fbaSOystein Eftevaag             return rval;
380*758e9fbaSOystein Eftevaag 
381*758e9fbaSOystein Eftevaag         rval = Tss2_Sys_GetCpBuffer(sysContext, &parametersSize, &startParams);
382*758e9fbaSOystein Eftevaag         if (rval != TPM2_RC_SUCCESS)
383*758e9fbaSOystein Eftevaag             return rval;
384*758e9fbaSOystein Eftevaag     } else {
385*758e9fbaSOystein Eftevaag         rval = Tss2_Sys_GetRpBuffer(sysContext, &parametersSize, &startParams);
386*758e9fbaSOystein Eftevaag         if (rval != TPM2_RC_SUCCESS)
387*758e9fbaSOystein Eftevaag             return rval;
388*758e9fbaSOystein Eftevaag 
389*758e9fbaSOystein Eftevaag         hashInputPtr = &(hashInput.buffer[hashInput.size]);
390*758e9fbaSOystein Eftevaag         /* This is response code. Assuming 0 (success) */
391*758e9fbaSOystein Eftevaag         *(UINT32 *)hashInputPtr = 0;
392*758e9fbaSOystein Eftevaag         hashInput.size += 4;
393*758e9fbaSOystein Eftevaag     }
394*758e9fbaSOystein Eftevaag 
395*758e9fbaSOystein Eftevaag     rval = Tss2_Sys_GetCommandCode(sysContext, (UINT8 *)&cmdCode);
396*758e9fbaSOystein Eftevaag     if (rval != TPM2_RC_SUCCESS)
397*758e9fbaSOystein Eftevaag         return rval;
398*758e9fbaSOystein Eftevaag 
399*758e9fbaSOystein Eftevaag     hashInputPtr = &(hashInput.buffer[hashInput.size]);
400*758e9fbaSOystein Eftevaag     *(UINT32 *)hashInputPtr = cmdCode;
401*758e9fbaSOystein Eftevaag     hashInput.size += 4;
402*758e9fbaSOystein Eftevaag 
403*758e9fbaSOystein Eftevaag     rval = ConcatSizedByteBuffer(&hashInput, (TPM2B *)&name1);
404*758e9fbaSOystein Eftevaag     if (rval != TPM2_RC_SUCCESS)
405*758e9fbaSOystein Eftevaag         return rval;
406*758e9fbaSOystein Eftevaag 
407*758e9fbaSOystein Eftevaag     rval = ConcatSizedByteBuffer(&hashInput, (TPM2B *)&name2);
408*758e9fbaSOystein Eftevaag     if (rval != TPM2_RC_SUCCESS)
409*758e9fbaSOystein Eftevaag         return rval;
410*758e9fbaSOystein Eftevaag 
411*758e9fbaSOystein Eftevaag     rval = ConcatSizedByteBuffer(&hashInput, (TPM2B *)&name3);
412*758e9fbaSOystein Eftevaag     if (rval != TPM2_RC_SUCCESS)
413*758e9fbaSOystein Eftevaag         return rval;
414*758e9fbaSOystein Eftevaag 
415*758e9fbaSOystein Eftevaag     if (hashInput.size + parametersSize > sizeof(hashInput.buffer))
416*758e9fbaSOystein Eftevaag         return TSS2_SYS_RC_INSUFFICIENT_BUFFER;
417*758e9fbaSOystein Eftevaag 
418*758e9fbaSOystein Eftevaag     for(i = 0; i < parametersSize; i++)
419*758e9fbaSOystein Eftevaag         hashInput.buffer[hashInput.size + i ] = startParams[i];
420*758e9fbaSOystein Eftevaag 
421*758e9fbaSOystein Eftevaag     hashInput.size += (UINT16)parametersSize;
422*758e9fbaSOystein Eftevaag     LOGBLOB_DEBUG(&hashInput.buffer[0], hashInput.size, "PHASH input bytes=");
423*758e9fbaSOystein Eftevaag 
424*758e9fbaSOystein Eftevaag     if (hashInput.size > sizeof(hashInput.buffer))
425*758e9fbaSOystein Eftevaag         return TSS2_SYS_RC_INSUFFICIENT_BUFFER;
426*758e9fbaSOystein Eftevaag 
427*758e9fbaSOystein Eftevaag     rval = hash(authHash, hashInput.buffer, hashInput.size, pHash);
428*758e9fbaSOystein Eftevaag     if (rval != TPM2_RC_SUCCESS)
429*758e9fbaSOystein Eftevaag         return rval;
430*758e9fbaSOystein Eftevaag 
431*758e9fbaSOystein Eftevaag     LOGBLOB_DEBUG(&pHash->buffer[0], pHash->size, "PHASH =");
432*758e9fbaSOystein Eftevaag     return rval;
433*758e9fbaSOystein Eftevaag }
434*758e9fbaSOystein Eftevaag 
tpm_handle_to_name(TSS2_TCTI_CONTEXT * tcti_context,TPM2_HANDLE handle,TPM2B_NAME * name)435*758e9fbaSOystein Eftevaag UINT32 tpm_handle_to_name(
436*758e9fbaSOystein Eftevaag     TSS2_TCTI_CONTEXT *tcti_context,
437*758e9fbaSOystein Eftevaag     TPM2_HANDLE handle,
438*758e9fbaSOystein Eftevaag     TPM2B_NAME *name)
439*758e9fbaSOystein Eftevaag {
440*758e9fbaSOystein Eftevaag     TSS2_RC rval;
441*758e9fbaSOystein Eftevaag     TPM2B_NAME qualified_name = TPM2B_NAME_INIT;
442*758e9fbaSOystein Eftevaag     TPM2B_PUBLIC public;
443*758e9fbaSOystein Eftevaag     TPM2B_NV_PUBLIC nvPublic;
444*758e9fbaSOystein Eftevaag     TSS2_SYS_CONTEXT *sysContext;
445*758e9fbaSOystein Eftevaag     UINT8 *namePtr;
446*758e9fbaSOystein Eftevaag 
447*758e9fbaSOystein Eftevaag     if (!tcti_context || !name)
448*758e9fbaSOystein Eftevaag         return TSS2_SYS_RC_BAD_VALUE;
449*758e9fbaSOystein Eftevaag 
450*758e9fbaSOystein Eftevaag     namePtr = name->name;
451*758e9fbaSOystein Eftevaag 
452*758e9fbaSOystein Eftevaag     if (handle == TPM2_RH_NULL) {
453*758e9fbaSOystein Eftevaag         name->size = 0;
454*758e9fbaSOystein Eftevaag         return TSS2_RC_SUCCESS;
455*758e9fbaSOystein Eftevaag     }
456*758e9fbaSOystein Eftevaag 
457*758e9fbaSOystein Eftevaag     switch(handle >> TPM2_HR_SHIFT)
458*758e9fbaSOystein Eftevaag     {
459*758e9fbaSOystein Eftevaag         case TPM2_HT_NV_INDEX:
460*758e9fbaSOystein Eftevaag             sysContext = sapi_init_from_tcti_ctx(tcti_context);
461*758e9fbaSOystein Eftevaag             if (sysContext == NULL)
462*758e9fbaSOystein Eftevaag                 return TSS2_SYS_RC_GENERAL_FAILURE;
463*758e9fbaSOystein Eftevaag 
464*758e9fbaSOystein Eftevaag             nvPublic.size = 0;
465*758e9fbaSOystein Eftevaag             rval = Tss2_Sys_NV_ReadPublic(sysContext, handle, 0,
466*758e9fbaSOystein Eftevaag                                           &nvPublic, name, 0);
467*758e9fbaSOystein Eftevaag             sapi_teardown(sysContext);
468*758e9fbaSOystein Eftevaag             break;
469*758e9fbaSOystein Eftevaag 
470*758e9fbaSOystein Eftevaag         case TPM2_HT_TRANSIENT:
471*758e9fbaSOystein Eftevaag         case TPM2_HT_PERSISTENT:
472*758e9fbaSOystein Eftevaag             sysContext = sapi_init_from_tcti_ctx(tcti_context);
473*758e9fbaSOystein Eftevaag             if (sysContext == NULL)
474*758e9fbaSOystein Eftevaag                 return TSS2_SYS_RC_GENERAL_FAILURE;
475*758e9fbaSOystein Eftevaag 
476*758e9fbaSOystein Eftevaag             public.size = 0;
477*758e9fbaSOystein Eftevaag             rval = Tss2_Sys_ReadPublic(sysContext, handle, 0,
478*758e9fbaSOystein Eftevaag                                        &public, name, &qualified_name, 0);
479*758e9fbaSOystein Eftevaag             sapi_teardown(sysContext);
480*758e9fbaSOystein Eftevaag             break;
481*758e9fbaSOystein Eftevaag 
482*758e9fbaSOystein Eftevaag         default:
483*758e9fbaSOystein Eftevaag             rval = TPM2_RC_SUCCESS;
484*758e9fbaSOystein Eftevaag             name->size = sizeof(TPM2_HANDLE);
485*758e9fbaSOystein Eftevaag             *(TPM2_HANDLE *)namePtr = BE_TO_HOST_32(handle);
486*758e9fbaSOystein Eftevaag     }
487*758e9fbaSOystein Eftevaag     return rval;
488*758e9fbaSOystein Eftevaag }
489*758e9fbaSOystein Eftevaag 
490*758e9fbaSOystein Eftevaag TSS2_RC
KDFa(TPMI_ALG_HASH hash,TPM2B * key,const char * label,TPM2B * contextU,TPM2B * contextV,UINT16 bits,TPM2B_MAX_BUFFER * result_key)491*758e9fbaSOystein Eftevaag KDFa(
492*758e9fbaSOystein Eftevaag     TPMI_ALG_HASH hash,
493*758e9fbaSOystein Eftevaag     TPM2B *key,
494*758e9fbaSOystein Eftevaag     const char *label,
495*758e9fbaSOystein Eftevaag     TPM2B *contextU,
496*758e9fbaSOystein Eftevaag     TPM2B *contextV,
497*758e9fbaSOystein Eftevaag     UINT16 bits,
498*758e9fbaSOystein Eftevaag     TPM2B_MAX_BUFFER *result_key)
499*758e9fbaSOystein Eftevaag {
500*758e9fbaSOystein Eftevaag     TPM2B_DIGEST digest;
501*758e9fbaSOystein Eftevaag     TPM2B_DIGEST tpm2blabel, tpm2bbits, tpm2bctr;
502*758e9fbaSOystein Eftevaag     TPM2B_DIGEST *buffer_list[8];
503*758e9fbaSOystein Eftevaag     UINT32 counter;
504*758e9fbaSOystein Eftevaag     TSS2_RC rval;
505*758e9fbaSOystein Eftevaag     int i, j;
506*758e9fbaSOystein Eftevaag     UINT16 bytes = bits / 8;
507*758e9fbaSOystein Eftevaag 
508*758e9fbaSOystein Eftevaag     result_key->size = 0;
509*758e9fbaSOystein Eftevaag     tpm2bctr.size = 4;
510*758e9fbaSOystein Eftevaag     tpm2bbits.size = 4;
511*758e9fbaSOystein Eftevaag     counter = BE_TO_HOST_32(bits);
512*758e9fbaSOystein Eftevaag     memcpy(tpm2bbits.buffer, &counter, 4);
513*758e9fbaSOystein Eftevaag     tpm2blabel.size = strlen(label) + 1;
514*758e9fbaSOystein Eftevaag     memcpy(tpm2blabel.buffer, label, tpm2blabel.size);
515*758e9fbaSOystein Eftevaag 
516*758e9fbaSOystein Eftevaag     LOG_DEBUG("KDFA, hash = %4.4x", hash);
517*758e9fbaSOystein Eftevaag     LOGBLOB_DEBUG(&key->buffer[0], key->size, "KDFA, key =");
518*758e9fbaSOystein Eftevaag     LOGBLOB_DEBUG(&tpm2blabel.buffer[0], tpm2blabel.size, "KDFA, tpm2blabel =");
519*758e9fbaSOystein Eftevaag     LOGBLOB_DEBUG(&contextU->buffer[0], contextU->size, "KDFA, contextU =");
520*758e9fbaSOystein Eftevaag     LOGBLOB_DEBUG(&contextV->buffer[0], contextV->size, "KDFA, contextV =");
521*758e9fbaSOystein Eftevaag 
522*758e9fbaSOystein Eftevaag     for (i = 1, j = 0; result_key->size < bytes; j = 0) {
523*758e9fbaSOystein Eftevaag         counter = BE_TO_HOST_32(i++);
524*758e9fbaSOystein Eftevaag         memcpy(tpm2bctr.buffer, &counter, 4);
525*758e9fbaSOystein Eftevaag         buffer_list[j++] = (TPM2B_DIGEST *)&tpm2bctr;
526*758e9fbaSOystein Eftevaag         buffer_list[j++] = (TPM2B_DIGEST *)&tpm2blabel;
527*758e9fbaSOystein Eftevaag         buffer_list[j++] = (TPM2B_DIGEST *)contextU;
528*758e9fbaSOystein Eftevaag         buffer_list[j++] = (TPM2B_DIGEST *)contextV;
529*758e9fbaSOystein Eftevaag         buffer_list[j++] = (TPM2B_DIGEST *)&tpm2bbits;
530*758e9fbaSOystein Eftevaag         buffer_list[j++] = NULL;
531*758e9fbaSOystein Eftevaag 
532*758e9fbaSOystein Eftevaag         for (j = 0; buffer_list[j] != NULL; j++) {
533*758e9fbaSOystein Eftevaag             LOGBLOB_DEBUG(&buffer_list[j]->buffer[0], buffer_list[j]->size, "bufferlist[%d]:", j);
534*758e9fbaSOystein Eftevaag             ;
535*758e9fbaSOystein Eftevaag         }
536*758e9fbaSOystein Eftevaag 
537*758e9fbaSOystein Eftevaag         rval = hmac(hash, key->buffer, key->size, buffer_list, &digest);
538*758e9fbaSOystein Eftevaag         if (rval != TPM2_RC_SUCCESS) {
539*758e9fbaSOystein Eftevaag             LOGBLOB_ERROR(digest.buffer, digest.size, "HMAC Failed rval = %d", rval);
540*758e9fbaSOystein Eftevaag             return rval;
541*758e9fbaSOystein Eftevaag         }
542*758e9fbaSOystein Eftevaag 
543*758e9fbaSOystein Eftevaag         ConcatSizedByteBuffer(result_key, (TPM2B *)&digest);
544*758e9fbaSOystein Eftevaag     }
545*758e9fbaSOystein Eftevaag 
546*758e9fbaSOystein Eftevaag     /* Truncate the result to the desired size. */
547*758e9fbaSOystein Eftevaag     result_key->size = bytes;
548*758e9fbaSOystein Eftevaag     LOGBLOB_DEBUG(result_key->buffer, result_key->size, "KDFA, key = ");
549*758e9fbaSOystein Eftevaag     return TPM2_RC_SUCCESS;
550*758e9fbaSOystein Eftevaag }
551*758e9fbaSOystein Eftevaag 
552*758e9fbaSOystein Eftevaag static TSS2_RC
gen_session_key(SESSION * session,TPM2B_MAX_BUFFER * session_key,TPM2B_IV * iv,TPM2B_AUTH * auth_value)553*758e9fbaSOystein Eftevaag gen_session_key(
554*758e9fbaSOystein Eftevaag     SESSION *session,
555*758e9fbaSOystein Eftevaag     TPM2B_MAX_BUFFER *session_key,
556*758e9fbaSOystein Eftevaag     TPM2B_IV *iv,
557*758e9fbaSOystein Eftevaag     TPM2B_AUTH *auth_value)
558*758e9fbaSOystein Eftevaag {
559*758e9fbaSOystein Eftevaag     TSS2_RC rval = TSS2_RC_SUCCESS;
560*758e9fbaSOystein Eftevaag     UINT32 aes_block_size = 16;
561*758e9fbaSOystein Eftevaag     TPM2B_MAX_BUFFER key, sessionValue;
562*758e9fbaSOystein Eftevaag 
563*758e9fbaSOystein Eftevaag     if (iv == NULL || session_key == NULL)
564*758e9fbaSOystein Eftevaag         return TSS2_SYS_RC_BAD_VALUE;
565*758e9fbaSOystein Eftevaag 
566*758e9fbaSOystein Eftevaag     CopySizedByteBuffer((TPM2B *)&sessionValue, (TPM2B *)&session->sessionKey);
567*758e9fbaSOystein Eftevaag     CatSizedByteBuffer((TPM2B *)&sessionValue, (TPM2B *)auth_value);
568*758e9fbaSOystein Eftevaag 
569*758e9fbaSOystein Eftevaag     rval = KDFa (session->authHash,
570*758e9fbaSOystein Eftevaag                  (TPM2B *)&sessionValue,
571*758e9fbaSOystein Eftevaag                  "CFB",
572*758e9fbaSOystein Eftevaag                  (TPM2B *)&session->nonceNewer,
573*758e9fbaSOystein Eftevaag                  (TPM2B *)&session->nonceOlder,
574*758e9fbaSOystein Eftevaag                  session->symmetric.keyBits.sym + aes_block_size * 8,
575*758e9fbaSOystein Eftevaag                  &key);
576*758e9fbaSOystein Eftevaag     if (rval != TSS2_RC_SUCCESS)
577*758e9fbaSOystein Eftevaag         return rval;
578*758e9fbaSOystein Eftevaag 
579*758e9fbaSOystein Eftevaag     if (key.size != (session->symmetric.keyBits.sym / 8) + aes_block_size)
580*758e9fbaSOystein Eftevaag         return TSS2_SYS_RC_GENERAL_FAILURE;
581*758e9fbaSOystein Eftevaag 
582*758e9fbaSOystein Eftevaag     iv->size = aes_block_size;
583*758e9fbaSOystein Eftevaag     session_key->size = (session->symmetric.keyBits.sym) / 8;
584*758e9fbaSOystein Eftevaag     UINT16 total_size = session_key->size + iv->size;
585*758e9fbaSOystein Eftevaag     if (iv->size > sizeof (iv->buffer) ||
586*758e9fbaSOystein Eftevaag          (total_size) > TPM2_MAX_DIGEST_BUFFER)
587*758e9fbaSOystein Eftevaag         return TSS2_SYS_RC_GENERAL_FAILURE;
588*758e9fbaSOystein Eftevaag 
589*758e9fbaSOystein Eftevaag     memcpy (iv->buffer, &key.buffer[session_key->size], iv->size);
590*758e9fbaSOystein Eftevaag     memcpy (session_key->buffer, key.buffer, session_key->size);
591*758e9fbaSOystein Eftevaag     return rval;
592*758e9fbaSOystein Eftevaag }
593*758e9fbaSOystein Eftevaag 
594*758e9fbaSOystein Eftevaag static TSS2_RC
encrypt_param_cfb(SESSION * session,TPM2B_MAX_BUFFER * encrypted_data,TPM2B_MAX_BUFFER * clear_data,TPM2B_AUTH * auth_value)595*758e9fbaSOystein Eftevaag encrypt_param_cfb(
596*758e9fbaSOystein Eftevaag     SESSION *session,
597*758e9fbaSOystein Eftevaag     TPM2B_MAX_BUFFER *encrypted_data,
598*758e9fbaSOystein Eftevaag     TPM2B_MAX_BUFFER *clear_data,
599*758e9fbaSOystein Eftevaag     TPM2B_AUTH *auth_value)
600*758e9fbaSOystein Eftevaag {
601*758e9fbaSOystein Eftevaag     TSS2_RC rval = TSS2_RC_SUCCESS;
602*758e9fbaSOystein Eftevaag     TPM2B_MAX_BUFFER encryptKey = TPM2B_MAX_BUFFER_INIT;
603*758e9fbaSOystein Eftevaag     TPM2B_IV iv = TPM2B_IV_INIT;
604*758e9fbaSOystein Eftevaag 
605*758e9fbaSOystein Eftevaag     rval = gen_session_key(session, &encryptKey, &iv, auth_value);
606*758e9fbaSOystein Eftevaag     if (rval)
607*758e9fbaSOystein Eftevaag         return rval;
608*758e9fbaSOystein Eftevaag 
609*758e9fbaSOystein Eftevaag     return encrypt_cfb(encrypted_data, clear_data, &encryptKey, &iv);
610*758e9fbaSOystein Eftevaag }
611*758e9fbaSOystein Eftevaag 
612*758e9fbaSOystein Eftevaag static TSS2_RC
decrypt_param_cfb(SESSION * session,TPM2B_MAX_BUFFER * clear_data,TPM2B_MAX_BUFFER * encrypted_data,TPM2B_AUTH * auth_value)613*758e9fbaSOystein Eftevaag decrypt_param_cfb(
614*758e9fbaSOystein Eftevaag     SESSION *session,
615*758e9fbaSOystein Eftevaag     TPM2B_MAX_BUFFER *clear_data,
616*758e9fbaSOystein Eftevaag     TPM2B_MAX_BUFFER *encrypted_data,
617*758e9fbaSOystein Eftevaag     TPM2B_AUTH *auth_value)
618*758e9fbaSOystein Eftevaag {
619*758e9fbaSOystein Eftevaag     TSS2_RC rval = TSS2_RC_SUCCESS;
620*758e9fbaSOystein Eftevaag     TPM2B_MAX_BUFFER encryptKey = TPM2B_MAX_BUFFER_INIT;
621*758e9fbaSOystein Eftevaag     TPM2B_IV iv = TPM2B_IV_INIT;
622*758e9fbaSOystein Eftevaag 
623*758e9fbaSOystein Eftevaag     rval = gen_session_key(session, &encryptKey, &iv, auth_value);
624*758e9fbaSOystein Eftevaag     if (rval)
625*758e9fbaSOystein Eftevaag         return rval;
626*758e9fbaSOystein Eftevaag 
627*758e9fbaSOystein Eftevaag     return decrypt_cfb(clear_data, encrypted_data, &encryptKey, &iv);
628*758e9fbaSOystein Eftevaag }
629*758e9fbaSOystein Eftevaag 
630*758e9fbaSOystein Eftevaag static TSS2_RC
encrypt_decrypt_xor(SESSION * session,TPM2B_MAX_BUFFER * output_data,TPM2B_MAX_BUFFER * input_data,TPM2B_AUTH * auth_value)631*758e9fbaSOystein Eftevaag encrypt_decrypt_xor(
632*758e9fbaSOystein Eftevaag     SESSION *session,
633*758e9fbaSOystein Eftevaag     TPM2B_MAX_BUFFER *output_data,
634*758e9fbaSOystein Eftevaag     TPM2B_MAX_BUFFER *input_data,
635*758e9fbaSOystein Eftevaag     TPM2B_AUTH *auth_value)
636*758e9fbaSOystein Eftevaag {
637*758e9fbaSOystein Eftevaag     TSS2_RC rval = TSS2_RC_SUCCESS;
638*758e9fbaSOystein Eftevaag     TPM2B_MAX_BUFFER key;
639*758e9fbaSOystein Eftevaag     TPM2B_MAX_BUFFER mask = { .size = 0, .buffer = 0 };
640*758e9fbaSOystein Eftevaag     UINT16 i;
641*758e9fbaSOystein Eftevaag     UINT16 size = input_data->size;
642*758e9fbaSOystein Eftevaag 
643*758e9fbaSOystein Eftevaag     if (size > TPM2_MAX_DIGEST_BUFFER) {
644*758e9fbaSOystein Eftevaag         LOG_ERROR("Bad value for inputData size: %" PRIu16, size);
645*758e9fbaSOystein Eftevaag         return TSS2_SYS_RC_GENERAL_FAILURE;
646*758e9fbaSOystein Eftevaag     }
647*758e9fbaSOystein Eftevaag 
648*758e9fbaSOystein Eftevaag     CopySizedByteBuffer((TPM2B *)&key, (TPM2B *)&session->sessionKey);
649*758e9fbaSOystein Eftevaag     CatSizedByteBuffer((TPM2B *)&key, (TPM2B *)auth_value);
650*758e9fbaSOystein Eftevaag 
651*758e9fbaSOystein Eftevaag     rval = KDFa(session->authHash,
652*758e9fbaSOystein Eftevaag             (TPM2B *)&key,
653*758e9fbaSOystein Eftevaag             "XOR",
654*758e9fbaSOystein Eftevaag             (TPM2B *)&session->nonceNewer,
655*758e9fbaSOystein Eftevaag             (TPM2B *)&session->nonceOlder,
656*758e9fbaSOystein Eftevaag             input_data->size * 8, &mask);
657*758e9fbaSOystein Eftevaag 
658*758e9fbaSOystein Eftevaag     if (rval)
659*758e9fbaSOystein Eftevaag         return rval;
660*758e9fbaSOystein Eftevaag 
661*758e9fbaSOystein Eftevaag     for (i = 0; i < size; i++)
662*758e9fbaSOystein Eftevaag         output_data->buffer[i] = input_data->buffer[i] ^ mask.buffer[i];
663*758e9fbaSOystein Eftevaag 
664*758e9fbaSOystein Eftevaag     output_data->size = size;
665*758e9fbaSOystein Eftevaag 
666*758e9fbaSOystein Eftevaag     return rval;
667*758e9fbaSOystein Eftevaag }
668*758e9fbaSOystein Eftevaag 
669*758e9fbaSOystein Eftevaag TSS2_RC
encrypt_command_param(SESSION * session,TPM2B_MAX_BUFFER * encrypted_data,TPM2B_MAX_BUFFER * clear_data,TPM2B_AUTH * auth_value)670*758e9fbaSOystein Eftevaag encrypt_command_param(
671*758e9fbaSOystein Eftevaag     SESSION *session,
672*758e9fbaSOystein Eftevaag     TPM2B_MAX_BUFFER *encrypted_data,
673*758e9fbaSOystein Eftevaag     TPM2B_MAX_BUFFER *clear_data,
674*758e9fbaSOystein Eftevaag     TPM2B_AUTH *auth_value)
675*758e9fbaSOystein Eftevaag {
676*758e9fbaSOystein Eftevaag     return session->symmetric.algorithm == TPM2_ALG_AES ?
677*758e9fbaSOystein Eftevaag         encrypt_param_cfb(session, encrypted_data, clear_data, auth_value) :
678*758e9fbaSOystein Eftevaag         encrypt_decrypt_xor(session, encrypted_data, clear_data, auth_value);
679*758e9fbaSOystein Eftevaag }
680*758e9fbaSOystein Eftevaag 
681*758e9fbaSOystein Eftevaag TSS2_RC
decrypt_response_param(SESSION * session,TPM2B_MAX_BUFFER * clear_data,TPM2B_MAX_BUFFER * encrypted_data,TPM2B_AUTH * auth_value)682*758e9fbaSOystein Eftevaag decrypt_response_param(
683*758e9fbaSOystein Eftevaag     SESSION *session,
684*758e9fbaSOystein Eftevaag     TPM2B_MAX_BUFFER *clear_data,
685*758e9fbaSOystein Eftevaag     TPM2B_MAX_BUFFER *encrypted_data,
686*758e9fbaSOystein Eftevaag     TPM2B_AUTH *auth_value)
687*758e9fbaSOystein Eftevaag {
688*758e9fbaSOystein Eftevaag     return session->symmetric.algorithm == TPM2_ALG_AES ?
689*758e9fbaSOystein Eftevaag         decrypt_param_cfb(session, clear_data, encrypted_data, auth_value) :
690*758e9fbaSOystein Eftevaag         encrypt_decrypt_xor(session, clear_data, encrypted_data, auth_value);
691*758e9fbaSOystein Eftevaag }
692