1 /* SPDX-License-Identifier: BSD-2-Clause */
2 /***********************************************************************
3  * Copyright (c) 2015 - 2018, Intel Corporation
4  *
5  * All rights reserved.
6  ***********************************************************************/
7 #ifdef HAVE_CONFIG_H
8 #include <config.h>
9 #endif
10 
11 #include <string.h>
12 
13 #include "util/tss2_endian.h"
14 #include "tss2_tpm2_types.h"
15 #include "tss2_mu.h"
16 #include "sysapi_util.h"
17 
Tss2_Sys_SetCmdAuths(TSS2_SYS_CONTEXT * sysContext,const TSS2L_SYS_AUTH_COMMAND * cmdAuthsArray)18 TSS2_RC Tss2_Sys_SetCmdAuths(
19     TSS2_SYS_CONTEXT *sysContext,
20     const TSS2L_SYS_AUTH_COMMAND *cmdAuthsArray)
21 {
22     _TSS2_SYS_CONTEXT_BLOB *ctx = syscontext_cast(sysContext);
23     uint16_t i;
24     UINT32 authSize = 0;
25     UINT32 newCmdSize = 0;
26     size_t authOffset;
27     TSS2_RC rval = TSS2_RC_SUCCESS;
28 
29     if (!ctx || !cmdAuthsArray)
30         return TSS2_SYS_RC_BAD_REFERENCE;
31 
32     if (cmdAuthsArray->count > TSS2_SYS_MAX_SESSIONS ||
33         cmdAuthsArray->count == 0)
34         return TSS2_SYS_RC_BAD_SIZE;
35 
36     if (ctx->previousStage != CMD_STAGE_PREPARE)
37         return TSS2_SYS_RC_BAD_SEQUENCE;
38 
39     if (!ctx->authAllowed)
40         return rval;
41 
42     ctx->authsCount = 0;
43 
44     req_header_from_cxt(ctx)->tag = HOST_TO_BE_16(TPM2_ST_SESSIONS);
45 
46     /* Calculate size needed for authorization area, check for any null
47      * pointers, and check for decrypt/encrypt sessions. */
48     for (i = 0; i < cmdAuthsArray->count; i++) {
49         authSize += sizeof(TPMI_SH_AUTH_SESSION);
50         authSize += sizeof(UINT16) + cmdAuthsArray->auths[i].nonce.size;
51         authSize += sizeof(UINT8);
52         authSize += sizeof(UINT16) + cmdAuthsArray->auths[i].hmac.size;
53     }
54 
55     newCmdSize = authSize;
56     newCmdSize += sizeof(UINT32); /* authorization size field */
57     newCmdSize += BE_TO_HOST_32(req_header_from_cxt(ctx)->commandSize);
58 
59     if (newCmdSize > ctx->maxCmdSize)
60         return TSS2_SYS_RC_INSUFFICIENT_CONTEXT;
61 
62     if (ctx->cpBufferUsedSize > ctx->maxCmdSize)
63         return TSS2_SYS_RC_INSUFFICIENT_CONTEXT;
64 
65     /* We're going to have to move stuff around.
66      * First move current cpBuffer down by the auth area size. */
67     memmove(ctx->cpBuffer + authSize + sizeof(UINT32),
68             ctx->cpBuffer, ctx->cpBufferUsedSize);
69 
70     /* Reset the auth size field */
71     memset(ctx->cpBuffer, 0, sizeof(UINT32));
72 
73     /* Now copy in the authorization area. */
74     authOffset = ctx->cpBuffer - ctx->cmdBuffer;
75     rval = Tss2_MU_UINT32_Marshal(authSize, ctx->cmdBuffer,
76                           newCmdSize, &authOffset);
77     if (rval)
78         return rval;
79 
80     for (i = 0; i < cmdAuthsArray->count; i++) {
81         rval = Tss2_MU_TPMS_AUTH_COMMAND_Marshal(&cmdAuthsArray->auths[i],
82                                          ctx->cmdBuffer, newCmdSize,
83                                          &authOffset);
84         if (rval)
85             break;
86     }
87 
88     ctx->cpBuffer += authSize + sizeof(UINT32);
89 
90     /* Now update the command size. */
91     req_header_from_cxt(ctx)->commandSize = HOST_TO_BE_32(newCmdSize);
92     ctx->authsCount = cmdAuthsArray->count;
93     return rval;
94 }
95