1 /* SPDX-License-Identifier: BSD-2-Clause */
2 /***********************************************************************;
3 * Copyright (c) 2015 - 2018, Intel Corporation
4 * All rights reserved.
5 ***********************************************************************/
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <string.h>
11
12 #include "tss2_tpm2_types.h"
13 #include "tss2_mu.h"
14 #include "sysapi_util.h"
15 #include "util/tss2_endian.h"
16
Tss2_Sys_SetDecryptParam(TSS2_SYS_CONTEXT * sysContext,size_t param_size,const uint8_t * param_buffer)17 TSS2_RC Tss2_Sys_SetDecryptParam(
18 TSS2_SYS_CONTEXT *sysContext,
19 size_t param_size,
20 const uint8_t *param_buffer)
21 {
22 _TSS2_SYS_CONTEXT_BLOB *ctx = syscontext_cast(sysContext);
23 size_t curr_param_size;
24 const uint8_t *curr_param_buffer;
25 UINT32 command_size;
26 const UINT8 *src, *limit;
27 UINT8 *dst;
28 UINT32 len;
29 TSS2_RC rval;
30
31 if (!param_buffer || !ctx)
32 return TSS2_SYS_RC_BAD_REFERENCE;
33
34 if (ctx->previousStage != CMD_STAGE_PREPARE)
35 return TSS2_SYS_RC_BAD_SEQUENCE;
36
37 if (ctx->decryptAllowed == 0)
38 return TSS2_SYS_RC_NO_DECRYPT_PARAM;
39
40 if (param_size < 1)
41 return TSS2_SYS_RC_BAD_VALUE;
42
43 if (BE_TO_HOST_32(req_header_from_cxt(ctx)->commandSize) +
44 param_size > ctx->maxCmdSize)
45 return TSS2_SYS_RC_INSUFFICIENT_CONTEXT;
46
47 rval = Tss2_Sys_GetDecryptParam(sysContext, &curr_param_size,
48 &curr_param_buffer);
49 if (rval)
50 return rval;
51
52 if (curr_param_size == 0 && ctx->decryptNull) {
53
54 /* Move the current cpBuffer down to make room for the decrypt param */
55 src = ctx->cpBuffer + 2;
56 dst = ctx->cpBuffer + ctx->cpBufferUsedSize + 2;
57 len = ctx->cpBufferUsedSize - 2;
58 limit = ctx->cmdBuffer + ctx->maxCmdSize;
59
60 if (dst + len > limit)
61 return TSS2_SYS_RC_INSUFFICIENT_CONTEXT;
62
63 memmove(dst, src, len);
64
65 ctx->cpBufferUsedSize += param_size;
66 *(UINT16 *)ctx->cpBuffer = HOST_TO_BE_16(param_size);
67
68 /* Fixup the command size */
69 command_size = BE_TO_HOST_32(req_header_from_cxt(ctx)->commandSize);
70 command_size += param_size;
71 req_header_from_cxt(ctx)->commandSize = HOST_TO_BE_32(command_size);
72 } else if (curr_param_size != param_size) {
73 return TSS2_SYS_RC_BAD_SIZE;
74 }
75
76 /* Copy the encrypted param into the command buffer */
77 src = param_buffer;
78 dst = (UINT8 *)curr_param_buffer;
79 len = param_size;
80 limit = ctx->cmdBuffer + ctx->maxCmdSize;
81
82 *(UINT16 *)ctx->cpBuffer = HOST_TO_BE_16(param_size);
83
84 if (dst + len > limit)
85 return TSS2_SYS_RC_INSUFFICIENT_CONTEXT;
86
87 memmove(dst, src, len);
88 return rval;
89 }
90