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