代码拉取完成,页面将自动刷新
From 406ee12062de2f8132ff10f1abc6887f32e6c03b Mon Sep 17 00:00:00 2001
From: mayuanchen <mayuanchen@hygon.cn>
Date: Tue, 9 May 2023 18:39:47 -0400
Subject: [PATCH 1/3] newfeature: tpm: add ecc encrypt/decrypt support.
Change-Id: I0176b508015a907e6dff48b8d8c90427b59f7a5e
---
include/tss2/tss2_esys.h | 61 +++++
include/tss2/tss2_mu.h | 14 +
include/tss2/tss2_sys.h | 46 ++++
include/tss2/tss2_tpm2_types.h | 13 +-
lib/tss2-esys.def | 6 +
lib/tss2-esys.map | 6 +
lib/tss2-mu.def | 2 +
lib/tss2-mu.map | 2 +
lib/tss2-sys.def | 6 +
lib/tss2-sys.map | 6 +
src/tss2-esys/api/Esys_ECC_Decrypt.c | 347 ++++++++++++++++++++++++
src/tss2-esys/api/Esys_ECC_Encrypt.c | 341 +++++++++++++++++++++++
src/tss2-mu/tpmt-types.c | 6 +
src/tss2-sys/api/Tss2_Sys_ECC_Decrypt.c | 153 +++++++++++
src/tss2-sys/api/Tss2_Sys_ECC_Encrypt.c | 153 +++++++++++
src/tss2-sys/sysapi_util.c | 4 +-
16 files changed, 1164 insertions(+), 2 deletions(-)
create mode 100644 src/tss2-esys/api/Esys_ECC_Decrypt.c
create mode 100644 src/tss2-esys/api/Esys_ECC_Encrypt.c
create mode 100644 src/tss2-sys/api/Tss2_Sys_ECC_Decrypt.c
create mode 100644 src/tss2-sys/api/Tss2_Sys_ECC_Encrypt.c
diff --git a/include/tss2/tss2_esys.h b/include/tss2/tss2_esys.h
index 6641f8d..fd06eeb 100644
--- a/include/tss2/tss2_esys.h
+++ b/include/tss2/tss2_esys.h
@@ -3759,6 +3759,67 @@ Esys_NV_Certify_Finish(
TPM2B_ATTEST **certifyInfo,
TPMT_SIGNATURE **signature);
+TSS2_RC
+Esys_ECC_Encrypt(
+ ESYS_CONTEXT *esysContext,
+ ESYS_TR keyHandle,
+ ESYS_TR shandle1,
+ ESYS_TR shandle2,
+ ESYS_TR shandle3,
+ const TPMT_ECC_DECRYPT *inScheme,
+ const TPM2B_MAX_BUFFER *message,
+ const TPM2B_DATA *sharedData1,
+ const TPM2B_DATA *sharedData2,
+ TPM2B_MAX_BUFFER **outData);
+
+TSS2_RC
+Esys_ECC_Encrypt_Async(
+ ESYS_CONTEXT *esysContext,
+ ESYS_TR keyHandle,
+ ESYS_TR shandle1,
+ ESYS_TR shandle2,
+ ESYS_TR shandle3,
+ const TPMT_ECC_DECRYPT *inScheme,
+ const TPM2B_MAX_BUFFER *message,
+ const TPM2B_DATA *sharedData1,
+ const TPM2B_DATA *sharedData2);
+
+TSS2_RC
+Esys_ECC_Encrypt_Finish(
+ ESYS_CONTEXT *esysContext,
+ TPM2B_MAX_BUFFER **outData);
+
+TSS2_RC
+Esys_ECC_Decrypt(
+ ESYS_CONTEXT *esysContext,
+ ESYS_TR keyHandle,
+ ESYS_TR shandle1,
+ ESYS_TR shandle2,
+ ESYS_TR shandle3,
+ const TPMT_ECC_DECRYPT *inScheme,
+ const TPM2B_MAX_BUFFER *message,
+ const TPM2B_DATA *sharedData1,
+ const TPM2B_DATA *sharedData2,
+ TPM2B_MAX_BUFFER **outData);
+
+TSS2_RC
+Esys_ECC_Decrypt_Async(
+ ESYS_CONTEXT *esysContext,
+ ESYS_TR keyHandle,
+ ESYS_TR shandle1,
+ ESYS_TR shandle2,
+ ESYS_TR shandle3,
+ const TPMT_ECC_DECRYPT *inScheme,
+ const TPM2B_MAX_BUFFER *message,
+ const TPM2B_DATA *sharedData1,
+ const TPM2B_DATA *sharedData2);
+
+TSS2_RC
+Esys_ECC_Decrypt_Finish(
+ ESYS_CONTEXT *esysContext,
+ TPM2B_MAX_BUFFER **outData);
+
+
/* Table 233 - TPM2_Vendor_TCG_Test Command */
TSS2_RC
diff --git a/include/tss2/tss2_mu.h b/include/tss2/tss2_mu.h
index 8933efc..25717d7 100644
--- a/include/tss2/tss2_mu.h
+++ b/include/tss2/tss2_mu.h
@@ -1800,6 +1800,20 @@ Tss2_MU_TPMT_RSA_DECRYPT_Unmarshal(
size_t *offset,
TPMT_RSA_DECRYPT *dest);
+TSS2_RC
+Tss2_MU_TPMT_ECC_DECRYPT_Marshal(
+ TPMT_ECC_DECRYPT const *src,
+ uint8_t buffer[],
+ size_t buffer_size,
+ size_t *offset);
+
+TSS2_RC
+Tss2_MU_TPMT_ECC_DECRYPT_Unmarshal(
+ uint8_t const buffer[],
+ size_t buffer_size,
+ size_t *offset,
+ TPMT_ECC_DECRYPT *dest);
+
TSS2_RC
Tss2_MU_TPMT_ECC_SCHEME_Marshal(
TPMT_ECC_SCHEME const *src,
diff --git a/include/tss2/tss2_sys.h b/include/tss2/tss2_sys.h
index a672898..80e42f6 100644
--- a/include/tss2/tss2_sys.h
+++ b/include/tss2/tss2_sys.h
@@ -2319,6 +2319,52 @@ TSS2_RC Tss2_Sys_PolicyAuthorizeNV(
TSS2L_SYS_AUTH_COMMAND const *cmdAuthsArray,
TSS2L_SYS_AUTH_RESPONSE *rspAuthsArray);
+TSS2_RC Tss2_Sys_ECC_Encrypt_Prepare(
+ TSS2_SYS_CONTEXT *sysContext,
+ TPMI_DH_OBJECT keyHandle,
+ const TPMT_ECC_DECRYPT *inScheme,
+ const TPM2B_MAX_BUFFER *message,
+ const TPM2B_DATA *sharedData1,
+ const TPM2B_DATA *sharedData2);
+
+TSS2_RC Tss2_Sys_ECC_Encrypt_Complete(
+ TSS2_SYS_CONTEXT *sysContext,
+ TPM2B_MAX_BUFFER *outData);
+
+TSS2_RC Tss2_Sys_ECC_Encrypt(
+ TSS2_SYS_CONTEXT *sysContext,
+ TPMI_DH_OBJECT keyHandle,
+ TSS2L_SYS_AUTH_COMMAND const *cmdAuthsArray,
+ const TPMT_ECC_DECRYPT *inScheme,
+ const TPM2B_MAX_BUFFER *message,
+ const TPM2B_DATA *sharedData1,
+ const TPM2B_DATA *sharedData2,
+ TPM2B_MAX_BUFFER *outData,
+ TSS2L_SYS_AUTH_RESPONSE *rspAuthsArray);
+
+TSS2_RC Tss2_Sys_ECC_Decrypt_Prepare(
+ TSS2_SYS_CONTEXT *sysContext,
+ TPMI_DH_OBJECT keyHandle,
+ const TPMT_ECC_DECRYPT *inScheme,
+ const TPM2B_MAX_BUFFER *message,
+ const TPM2B_DATA *sharedData1,
+ const TPM2B_DATA *sharedData2);
+
+TSS2_RC Tss2_Sys_ECC_Decrypt_Complete(
+ TSS2_SYS_CONTEXT *sysContext,
+ TPM2B_MAX_BUFFER *outData);
+
+TSS2_RC Tss2_Sys_ECC_Decrypt(
+ TSS2_SYS_CONTEXT *sysContext,
+ TPMI_DH_OBJECT keyHandle,
+ TSS2L_SYS_AUTH_COMMAND const *cmdAuthsArray,
+ const TPMT_ECC_DECRYPT *inScheme,
+ const TPM2B_MAX_BUFFER *message,
+ const TPM2B_DATA *sharedData1,
+ const TPM2B_DATA *sharedData2,
+ TPM2B_MAX_BUFFER *outData,
+ TSS2L_SYS_AUTH_RESPONSE *rspAuthsArray);
+
#ifdef __cplusplus
}
#endif
diff --git a/include/tss2/tss2_tpm2_types.h b/include/tss2/tss2_tpm2_types.h
index 1ce737e..c5f53d9 100644
--- a/include/tss2/tss2_tpm2_types.h
+++ b/include/tss2/tss2_tpm2_types.h
@@ -249,7 +249,9 @@ typedef UINT32 TPM2_CC;
#define TPM2_CC_Policy_AC_SendSelect ((TPM2_CC) 0x00000196)
#define TPM2_CC_CertifyX509 ((TPM2_CC) 0x00000197)
#define TPM2_CC_ACT_SetTimeout ((TPM2_CC) 0x00000198)
-#define TPM2_CC_LAST ((TPM2_CC) 0x00000198)
+#define TPM2_CC_ECC_Encrypt ((TPM2_CC) 0x00000199)
+#define TPM2_CC_ECC_Decrypt ((TPM2_CC) 0x0000019a)
+#define TPM2_CC_LAST ((TPM2_CC) 0x0000019a)
#define TPM2_CC_Vendor_TCG_Test ((TPM2_CC) 0x20000000)
/* Definition of Types for Documentation Clarity */
@@ -1630,6 +1632,15 @@ struct TPM2B_PRIVATE_KEY_RSA {
BYTE buffer[TPM2_MAX_RSA_KEY_BYTES/2 * 5];
};
+/* Definition of TPM2_ALG_ID ECC TPMI_ALG_ECC_DECRYPT Type */
+typedef TPM2_ALG_ID TPMI_ALG_ECC_DECRYPT;
+
+/* Definition of ECC TPMT_ECC_DECRYPT Structure */
+typedef struct {
+ TPMI_ALG_ECC_DECRYPT scheme; /* scheme selector */
+ TPMU_ASYM_SCHEME details; /* scheme parameters */
+} TPMT_ECC_DECRYPT;
+
/* Definition of ECC TPM2B_ECC_PARAMETER Structure */
typedef struct TPM2B_ECC_PARAMETER TPM2B_ECC_PARAMETER;
struct TPM2B_ECC_PARAMETER {
diff --git a/lib/tss2-esys.def b/lib/tss2-esys.def
index c6890d8..3b762f7 100644
--- a/lib/tss2-esys.def
+++ b/lib/tss2-esys.def
@@ -66,6 +66,12 @@ EXPORTS
Esys_Duplicate
Esys_Duplicate_Async
Esys_Duplicate_Finish
+ Esys_ECC_Decrypt
+ Esys_ECC_Decrypt_Async
+ Esys_ECC_Decrypt_Finish
+ Esys_ECC_Encrypt
+ Esys_ECC_Encrypt_Async
+ Esys_ECC_Encrypt_Finish
Esys_ECC_Parameters
Esys_ECC_Parameters_Async
Esys_ECC_Parameters_Finish
diff --git a/lib/tss2-esys.map b/lib/tss2-esys.map
index 2062cc3..6884075 100644
--- a/lib/tss2-esys.map
+++ b/lib/tss2-esys.map
@@ -66,6 +66,12 @@
Esys_Duplicate;
Esys_Duplicate_Async;
Esys_Duplicate_Finish;
+ Esys_ECC_Decrypt;
+ Esys_ECC_Decrypt_Async;
+ Esys_ECC_Decrypt_Finish;
+ Esys_ECC_Encrypt;
+ Esys_ECC_Encrypt_Async;
+ Esys_ECC_Encrypt_Finish;
Esys_ECC_Parameters;
Esys_ECC_Parameters_Async;
Esys_ECC_Parameters_Finish;
diff --git a/lib/tss2-mu.def b/lib/tss2-mu.def
index d978c83..7b2e957 100644
--- a/lib/tss2-mu.def
+++ b/lib/tss2-mu.def
@@ -284,3 +284,5 @@ EXPORTS
Tss2_MU_TPM2_NT_Unmarshal
Tss2_MU_TPMI_ALG_HASH_Marshal
Tss2_MU_TPMI_ALG_HASH_Unmarshal
+ Tss2_MU_TPMT_ECC_DECRYPT_Marshal
+ Tss2_MU_TPMT_ECC_DECRYPT_Unmarshal
diff --git a/lib/tss2-mu.map b/lib/tss2-mu.map
index 3f4c8cb..2149a5f 100644
--- a/lib/tss2-mu.map
+++ b/lib/tss2-mu.map
@@ -284,6 +284,8 @@
Tss2_MU_TPM2_NT_Unmarshal;
Tss2_MU_TPMI_ALG_HASH_Marshal;
Tss2_MU_TPMI_ALG_HASH_Unmarshal;
+ Tss2_MU_TPMT_ECC_DECRYPT_Marshal;
+ Tss2_MU_TPMT_ECC_DECRYPT_Unmarshal;
local:
*;
};
diff --git a/lib/tss2-sys.def b/lib/tss2-sys.def
index 751ef33..b25dcd9 100644
--- a/lib/tss2-sys.def
+++ b/lib/tss2-sys.def
@@ -372,3 +372,9 @@ EXPORTS
Tss2_Sys_ZGen_2Phase_Prepare
Tss2_Sys_ZGen_2Phase_Complete
Tss2_Sys_ZGen_2Phase
+ Tss2_Sys_ECC_Encrypt_Prepare
+ Tss2_Sys_ECC_Encrypt_Complete
+ Tss2_Sys_ECC_Encrypt
+ Tss2_Sys_ECC_Decrypt_Prepare
+ Tss2_Sys_ECC_Decrypt_Complete
+ Tss2_Sys_ECC_Decrypt
diff --git a/lib/tss2-sys.map b/lib/tss2-sys.map
index 0027df9..eba70f7 100644
--- a/lib/tss2-sys.map
+++ b/lib/tss2-sys.map
@@ -376,6 +376,12 @@
Tss2_Sys_ZGen_2Phase_Prepare;
Tss2_Sys_ZGen_2Phase_Complete;
Tss2_Sys_ZGen_2Phase;
+ Tss2_Sys_ECC_Encrypt_Prepare;
+ Tss2_Sys_ECC_Encrypt_Complete;
+ Tss2_Sys_ECC_Encrypt;
+ Tss2_Sys_ECC_Decrypt_Prepare;
+ Tss2_Sys_ECC_Decrypt_Complete;
+ Tss2_Sys_ECC_Decrypt;
local:
*;
};
diff --git a/src/tss2-esys/api/Esys_ECC_Decrypt.c b/src/tss2-esys/api/Esys_ECC_Decrypt.c
new file mode 100644
index 0000000..1515563
--- /dev/null
+++ b/src/tss2-esys/api/Esys_ECC_Decrypt.c
@@ -0,0 +1,347 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+/*******************************************************************************
+ * Copyright 2017-2018, Fraunhofer SIT sponsored by Infineon Technologies AG
+ * All rights reserved.
+ ******************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "tss2_mu.h"
+#include "tss2_sys.h"
+#include "tss2_esys.h"
+
+#include "esys_types.h"
+#include "esys_iutil.h"
+#include "esys_mu.h"
+#define LOGMODULE esys
+#include "util/log.h"
+#include "util/aux_util.h"
+
+/** One-Call function for TPM2_ECC_Decrypt
+ *
+ * This function invokes the TPM2_ECC_Decrypt command in a one-call
+ * variant. This means the function will block until the TPM response is
+ * available. All input parameters are const. The memory for non-simple output
+ * parameters is allocated by the function implementation.
+ *
+ * @param[in,out] esysContext The ESYS_CONTEXT.
+ * @param[in] keyHandle Reference to public portion of ECC key to use for
+ * encryption.
+ * @param[in] shandle1 First session handle.
+ * @param[in] shandle2 Second session handle.
+ * @param[in] shandle3 Third session handle.
+ * @param[in] inScheme TPM2_The padding scheme to use if scheme associated with
+ * keyHandle is TPM2_ALG_NULL.
+ * @param[in] cipherText Cipher text to be decrypted.
+ * @param[in] sharedData1 Optional sharedData1 to be associated with the inScheme.
+ * @param[in] sharedData2 Optional sharedData2 to be associated with the inScheme.
+ * @param[out] outData Encrypted output.
+ * (callee-allocated)
+ * @retval TSS2_RC_SUCCESS if the function call was a success.
+ * @retval TSS2_ESYS_RC_BAD_REFERENCE if the esysContext or required input
+ * pointers or required output handle references are NULL.
+ * @retval TSS2_ESYS_RC_BAD_CONTEXT: if esysContext corruption is detected.
+ * @retval TSS2_ESYS_RC_MEMORY: if the ESAPI cannot allocate enough memory for
+ * internal operations or return parameters.
+ * @retval TSS2_ESYS_RC_BAD_SEQUENCE: if the context has an asynchronous
+ * operation already pending.
+ * @retval TSS2_ESYS_RC_INSUFFICIENT_RESPONSE: if the TPM's response does not
+ * at least contain the tag, response length, and response code.
+ * @retval TSS2_ESYS_RC_MALFORMED_RESPONSE: if the TPM's response is corrupted.
+ * @retval TSS2_ESYS_RC_RSP_AUTH_FAILED: if the response HMAC from the TPM
+ did not verify.
+ * @retval TSS2_ESYS_RC_MULTIPLE_DECRYPT_SESSIONS: if more than one session has
+ * the 'decrypt' attribute bit set.
+ * @retval TSS2_ESYS_RC_MULTIPLE_ENCRYPT_SESSIONS: if more than one session has
+ * the 'encrypt' attribute bit set.
+ * @retval TSS2_ESYS_RC_BAD_TR: if any of the ESYS_TR objects are unknown
+ * to the ESYS_CONTEXT or are of the wrong type or if required
+ * ESYS_TR objects are ESYS_TR_NONE.
+ * @retval TSS2_RCs produced by lower layers of the software stack may be
+ * returned to the caller unaltered unless handled internally.
+ */
+TSS2_RC
+Esys_ECC_Decrypt(
+ ESYS_CONTEXT *esysContext,
+ ESYS_TR keyHandle,
+ ESYS_TR shandle1,
+ ESYS_TR shandle2,
+ ESYS_TR shandle3,
+ const TPMT_ECC_DECRYPT *inScheme,
+ const TPM2B_MAX_BUFFER *cipherText,
+ const TPM2B_DATA *sharedData1,
+ const TPM2B_DATA *sharedData2,
+ TPM2B_MAX_BUFFER **outData)
+{
+ TSS2_RC r;
+
+ r = Esys_ECC_Decrypt_Async(esysContext, keyHandle, shandle1, shandle2,
+ shandle3, inScheme, cipherText, sharedData1, sharedData2);
+ return_if_error(r, "Error in async function");
+
+ /* Set the timeout to indefinite for now, since we want _Finish to block */
+ int32_t timeouttmp = esysContext->timeout;
+ esysContext->timeout = -1;
+ /*
+ * Now we call the finish function, until return code is not equal to
+ * from TSS2_BASE_RC_TRY_AGAIN.
+ * Note that the finish function may return TSS2_RC_TRY_AGAIN, even if we
+ * have set the timeout to -1. This occurs for example if the TPM requests
+ * a retransmission of the command via TPM2_RC_YIELDED.
+ */
+ do {
+ r = Esys_ECC_Decrypt_Finish(esysContext, outData);
+ /* This is just debug information about the reattempt to finish the
+ command */
+ if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN)
+ LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32
+ " => resubmitting command", r);
+ } while ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN);
+
+ /* Restore the timeout value to the original value */
+ esysContext->timeout = timeouttmp;
+ return_if_error(r, "Esys Finish");
+
+ return TSS2_RC_SUCCESS;
+}
+
+/** Asynchronous function for TPM2_ECC_Decrypt
+ *
+ * This function invokes the TPM2_ECC_Decrypt command in a asynchronous
+ * variant. This means the function will return as soon as the command has been
+ * sent downwards the stack to the TPM. All input parameters are const.
+ * In order to retrieve the TPM's response call Esys_ECC_Decrypt_Finish.
+ *
+ * @param[in,out] esysContext The ESYS_CONTEXT.
+ * @param[in] keyHandle Reference to public portion of ECC key to use for
+ * encryption.
+ * @param[in] shandle1 First session handle.
+ * @param[in] shandle2 Second session handle.
+ * @param[in] shandle3 Third session handle.
+ * @param[in] inScheme TPM2_The padding scheme to use if scheme associated with
+ * keyHandle is TPM2_ALG_NULL.
+ * @param[in] cipherText Cipher text to be decrypted.
+ * @param[in] sharedData1 Optional sharedData1 to be associated with the inScheme.
+ * @param[in] sharedData2 Optional sharedData2 to be associated with the inScheme.
+ * @retval ESYS_RC_SUCCESS if the function call was a success.
+ * @retval TSS2_ESYS_RC_BAD_REFERENCE if the esysContext or required input
+ * pointers or required output handle references are NULL.
+ * @retval TSS2_ESYS_RC_BAD_CONTEXT: if esysContext corruption is detected.
+ * @retval TSS2_ESYS_RC_MEMORY: if the ESAPI cannot allocate enough memory for
+ * internal operations or return parameters.
+ * @retval TSS2_RCs produced by lower layers of the software stack may be
+ returned to the caller unaltered unless handled internally.
+ * @retval TSS2_ESYS_RC_MULTIPLE_DECRYPT_SESSIONS: if more than one session has
+ * the 'decrypt' attribute bit set.
+ * @retval TSS2_ESYS_RC_MULTIPLE_ENCRYPT_SESSIONS: if more than one session has
+ * the 'encrypt' attribute bit set.
+ * @retval TSS2_ESYS_RC_BAD_TR: if any of the ESYS_TR objects are unknown
+ * to the ESYS_CONTEXT or are of the wrong type or if required
+ * ESYS_TR objects are ESYS_TR_NONE.
+ */
+TSS2_RC
+Esys_ECC_Decrypt_Async(
+ ESYS_CONTEXT *esysContext,
+ ESYS_TR keyHandle,
+ ESYS_TR shandle1,
+ ESYS_TR shandle2,
+ ESYS_TR shandle3,
+ const TPMT_ECC_DECRYPT *inScheme,
+ const TPM2B_MAX_BUFFER *cipherText,
+ const TPM2B_DATA *sharedData1,
+ const TPM2B_DATA *sharedData2)
+{
+ TSS2_RC r;
+ LOG_TRACE("context=%p, keyHandle=%"PRIx32 ", cipherText=%p,"
+ "inScheme=%p, sharedData1=%p, sharedData2=%p",
+ esysContext, keyHandle, cipherText, inScheme, sharedData1, sharedData2);
+ TSS2L_SYS_AUTH_COMMAND auths;
+ RSRC_NODE_T *keyHandleNode;
+
+ /* Check context, sequence correctness and set state to error for now */
+ if (esysContext == NULL) {
+ LOG_ERROR("esyscontext is NULL.");
+ return TSS2_ESYS_RC_BAD_REFERENCE;
+ }
+ r = iesys_check_sequence_async(esysContext);
+ if (r != TSS2_RC_SUCCESS)
+ return r;
+ esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+ /* Check input parameters */
+ r = check_session_feasibility(shandle1, shandle2, shandle3, 1);
+ return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
+
+ /* Retrieve the metadata objects for provided handles */
+ r = esys_GetResourceObject(esysContext, keyHandle, &keyHandleNode);
+ return_state_if_error(r, _ESYS_STATE_INIT, "keyHandle unknown.");
+
+ /* Initial invocation of SAPI to prepare the command buffer with parameters */
+ r = Tss2_Sys_ECC_Decrypt_Prepare(esysContext->sys,
+ (keyHandleNode == NULL) ? TPM2_RH_NULL
+ : keyHandleNode->rsrc.handle, inScheme,
+ cipherText, sharedData1, sharedData2);
+ return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
+
+ /* Calculate the cpHash Values */
+ r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+ return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
+ if (keyHandleNode != NULL)
+ iesys_compute_session_value(esysContext->session_tab[0],
+ &keyHandleNode->rsrc.name, &keyHandleNode->auth);
+ else
+ iesys_compute_session_value(esysContext->session_tab[0], NULL, NULL);
+
+ iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
+ iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
+
+ /* Generate the auth values and set them in the SAPI command buffer */
+ r = iesys_gen_auths(esysContext, keyHandleNode, NULL, NULL, &auths);
+ return_state_if_error(r, _ESYS_STATE_INIT,
+ "Error in computation of auth values");
+
+ esysContext->authsCount = auths.count;
+ if (auths.count > 0) {
+ r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
+ return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
+ }
+
+ /* Trigger execution and finish the async invocation */
+ r = Tss2_Sys_ExecuteAsync(esysContext->sys);
+ return_state_if_error(r, _ESYS_STATE_INTERNALERROR,
+ "Finish (Execute Async)");
+
+ esysContext->state = _ESYS_STATE_SENT;
+
+ return r;
+}
+
+/** Asynchronous finish function for TPM2_ECC_Decrypt
+ *
+ * This function returns the results of a TPM2_ECC_Decrypt command
+ * invoked via Esys_ECC_Decrypt_Finish. All non-simple output parameters
+ * are allocated by the function's implementation. NULL can be passed for every
+ * output parameter if the value is not required.
+ *
+ * @param[in,out] esysContext The ESYS_CONTEXT.
+ * @param[out] outData Decrypted output.
+ * (callee-allocated)
+ * @retval TSS2_RC_SUCCESS on success
+ * @retval ESYS_RC_SUCCESS if the function call was a success.
+ * @retval TSS2_ESYS_RC_BAD_REFERENCE if the esysContext or required input
+ * pointers or required output handle references are NULL.
+ * @retval TSS2_ESYS_RC_BAD_CONTEXT: if esysContext corruption is detected.
+ * @retval TSS2_ESYS_RC_MEMORY: if the ESAPI cannot allocate enough memory for
+ * internal operations or return parameters.
+ * @retval TSS2_ESYS_RC_BAD_SEQUENCE: if the context has an asynchronous
+ * operation already pending.
+ * @retval TSS2_ESYS_RC_TRY_AGAIN: if the timeout counter expires before the
+ * TPM response is received.
+ * @retval TSS2_ESYS_RC_INSUFFICIENT_RESPONSE: if the TPM's response does not
+ * at least contain the tag, response length, and response code.
+ * @retval TSS2_ESYS_RC_RSP_AUTH_FAILED: if the response HMAC from the TPM did
+ * not verify.
+ * @retval TSS2_ESYS_RC_MALFORMED_RESPONSE: if the TPM's response is corrupted.
+ * @retval TSS2_RCs produced by lower layers of the software stack may be
+ * returned to the caller unaltered unless handled internally.
+ */
+TSS2_RC
+Esys_ECC_Decrypt_Finish(
+ ESYS_CONTEXT *esysContext,
+ TPM2B_MAX_BUFFER **outData)
+{
+ TSS2_RC r;
+ LOG_TRACE("context=%p, outData=%p",
+ esysContext, outData);
+
+ if (esysContext == NULL) {
+ LOG_ERROR("esyscontext is NULL.");
+ return TSS2_ESYS_RC_BAD_REFERENCE;
+ }
+
+ /* Check for correct sequence and set sequence to irregular for now */
+ if (esysContext->state != _ESYS_STATE_SENT &&
+ esysContext->state != _ESYS_STATE_RESUBMISSION) {
+ LOG_ERROR("Esys called in bad sequence.");
+ return TSS2_ESYS_RC_BAD_SEQUENCE;
+ }
+ esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+ /* Allocate memory for response parameters */
+ if (outData != NULL) {
+ *outData = calloc(sizeof(TPM2B_MAX_BUFFER), 1);
+ if (*outData == NULL) {
+ return_error(TSS2_ESYS_RC_MEMORY, "Out of memory");
+ }
+ }
+
+ /*Receive the TPM response and handle resubmissions if necessary. */
+ r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
+ if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
+ LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+ esysContext->state = _ESYS_STATE_SENT;
+ goto error_cleanup;
+ }
+ /* This block handle the resubmission of TPM commands given a certain set of
+ * TPM response codes. */
+ if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
+ LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
+ "resubmission: %" PRIx32, r);
+ if (esysContext->submissionCount++ >= _ESYS_MAX_SUBMISSIONS) {
+ LOG_WARNING("Maximum number of (re)submissions has been reached.");
+ esysContext->state = _ESYS_STATE_INIT;
+ goto error_cleanup;
+ }
+ esysContext->state = _ESYS_STATE_RESUBMISSION;
+ r = Tss2_Sys_ExecuteAsync(esysContext->sys);
+ if (r != TSS2_RC_SUCCESS) {
+ LOG_WARNING("Error attempting to resubmit");
+ /* We do not set esysContext->state here but inherit the most recent
+ * state of the _async function. */
+ goto error_cleanup;
+ }
+ r = TSS2_ESYS_RC_TRY_AGAIN;
+ LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
+ goto error_cleanup;
+ }
+ /* The following is the "regular error" handling. */
+ if (iesys_tpm_error(r)) {
+ LOG_WARNING("Received TPM Error");
+ esysContext->state = _ESYS_STATE_INIT;
+ goto error_cleanup;
+ } else if (r != TSS2_RC_SUCCESS) {
+ LOG_ERROR("Received a non-TPM Error");
+ esysContext->state = _ESYS_STATE_INTERNALERROR;
+ goto error_cleanup;
+ }
+
+ /*
+ * Now the verification of the response (hmac check) and if necessary the
+ * parameter decryption have to be done.
+ */
+ r = iesys_check_response(esysContext);
+ goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response",
+ error_cleanup);
+
+ /*
+ * After the verification of the response we call the complete function
+ * to deliver the result.
+ */
+ r = Tss2_Sys_ECC_Decrypt_Complete(esysContext->sys,
+ (outData != NULL) ? *outData : NULL);
+ goto_state_if_error(r, _ESYS_STATE_INTERNALERROR,
+ "Received error from SAPI unmarshaling" ,
+ error_cleanup);
+
+ esysContext->state = _ESYS_STATE_INIT;
+
+ return TSS2_RC_SUCCESS;
+
+error_cleanup:
+ if (outData != NULL)
+ SAFE_FREE(*outData);
+
+ return r;
+}
diff --git a/src/tss2-esys/api/Esys_ECC_Encrypt.c b/src/tss2-esys/api/Esys_ECC_Encrypt.c
new file mode 100644
index 0000000..498bca6
--- /dev/null
+++ b/src/tss2-esys/api/Esys_ECC_Encrypt.c
@@ -0,0 +1,341 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+/*******************************************************************************
+ * Copyright 2017-2018, Fraunhofer SIT sponsored by Infineon Technologies AG
+ * All rights reserved.
+ ******************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "tss2_mu.h"
+#include "tss2_sys.h"
+#include "tss2_esys.h"
+
+#include "esys_types.h"
+#include "esys_iutil.h"
+#include "esys_mu.h"
+#define LOGMODULE esys
+#include "util/log.h"
+#include "util/aux_util.h"
+
+/** One-Call function for TPM2_ECC_Encrypt
+ *
+ * This function invokes the TPM2_ECC_Encrypt command in a one-call
+ * variant. This means the function will block until the TPM response is
+ * available. All input parameters are const. The memory for non-simple output
+ * parameters is allocated by the function implementation.
+ *
+ * @param[in,out] esysContext The ESYS_CONTEXT.
+ * @param[in] keyHandle Reference to public portion of ECC key to use for
+ * encryption.
+ * @param[in] shandle1 First session handle.
+ * @param[in] shandle2 Second session handle.
+ * @param[in] shandle3 Third session handle.
+ * @param[in] inScheme TPM2_The padding scheme to use if scheme associated with
+ * keyHandle is TPM2_ALG_NULL.
+ * @param[in] message Message to be encrypted.
+ * @param[in] sharedData1 Optional sharedData1 to be associated with the inScheme.
+ * @param[in] sharedData2 Optional sharedData2 to be associated with the inScheme.
+ * @param[out] outData Encrypted output.
+ * (callee-allocated)
+ * @retval TSS2_RC_SUCCESS if the function call was a success.
+ * @retval TSS2_ESYS_RC_BAD_REFERENCE if the esysContext or required input
+ * pointers or required output handle references are NULL.
+ * @retval TSS2_ESYS_RC_BAD_CONTEXT: if esysContext corruption is detected.
+ * @retval TSS2_ESYS_RC_MEMORY: if the ESAPI cannot allocate enough memory for
+ * internal operations or return parameters.
+ * @retval TSS2_ESYS_RC_BAD_SEQUENCE: if the context has an asynchronous
+ * operation already pending.
+ * @retval TSS2_ESYS_RC_INSUFFICIENT_RESPONSE: if the TPM's response does not
+ * at least contain the tag, response length, and response code.
+ * @retval TSS2_ESYS_RC_MALFORMED_RESPONSE: if the TPM's response is corrupted.
+ * @retval TSS2_ESYS_RC_RSP_AUTH_FAILED: if the response HMAC from the TPM
+ did not verify.
+ * @retval TSS2_ESYS_RC_MULTIPLE_DECRYPT_SESSIONS: if more than one session has
+ * the 'decrypt' attribute bit set.
+ * @retval TSS2_ESYS_RC_MULTIPLE_ENCRYPT_SESSIONS: if more than one session has
+ * the 'encrypt' attribute bit set.
+ * @retval TSS2_ESYS_RC_BAD_TR: if any of the ESYS_TR objects are unknown
+ * to the ESYS_CONTEXT or are of the wrong type or if required
+ * ESYS_TR objects are ESYS_TR_NONE.
+ * @retval TSS2_RCs produced by lower layers of the software stack may be
+ * returned to the caller unaltered unless handled internally.
+ */
+TSS2_RC
+Esys_ECC_Encrypt(
+ ESYS_CONTEXT *esysContext,
+ ESYS_TR keyHandle,
+ ESYS_TR shandle1,
+ ESYS_TR shandle2,
+ ESYS_TR shandle3,
+ const TPMT_ECC_DECRYPT *inScheme,
+ const TPM2B_MAX_BUFFER *message,
+ const TPM2B_DATA *sharedData1,
+ const TPM2B_DATA *sharedData2,
+ TPM2B_MAX_BUFFER **outData)
+{
+ TSS2_RC r;
+
+ r = Esys_ECC_Encrypt_Async(esysContext, keyHandle, shandle1, shandle2,
+ shandle3, inScheme, message, sharedData1, sharedData2);
+ return_if_error(r, "Error in async function");
+
+ /* Set the timeout to indefinite for now, since we want _Finish to block */
+ int32_t timeouttmp = esysContext->timeout;
+ esysContext->timeout = -1;
+ /*
+ * Now we call the finish function, until return code is not equal to
+ * from TSS2_BASE_RC_TRY_AGAIN.
+ * Note that the finish function may return TSS2_RC_TRY_AGAIN, even if we
+ * have set the timeout to -1. This occurs for example if the TPM requests
+ * a retransmission of the command via TPM2_RC_YIELDED.
+ */
+ do {
+ r = Esys_ECC_Encrypt_Finish(esysContext, outData);
+ /* This is just debug information about the reattempt to finish the
+ command */
+ if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN)
+ LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32
+ " => resubmitting command", r);
+ } while ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN);
+
+ /* Restore the timeout value to the original value */
+ esysContext->timeout = timeouttmp;
+ return_if_error(r, "Esys Finish");
+
+ return TSS2_RC_SUCCESS;
+}
+
+/** Asynchronous function for TPM2_ECC_Encrypt
+ *
+ * This function invokes the TPM2_ECC_Encrypt command in a asynchronous
+ * variant. This means the function will return as soon as the command has been
+ * sent downwards the stack to the TPM. All input parameters are const.
+ * In order to retrieve the TPM's response call Esys_ECC_Encrypt_Finish.
+ *
+ * @param[in,out] esysContext The ESYS_CONTEXT.
+ * @param[in] keyHandle Reference to public portion of ECC key to use for
+ * encryption.
+ * @param[in] shandle1 First session handle.
+ * @param[in] shandle2 Second session handle.
+ * @param[in] shandle3 Third session handle.
+ * @param[in] message Message to be encrypted.
+ * @param[in] inScheme TPM2_The padding scheme to use if scheme associated with
+ * keyHandle is TPM2_ALG_NULL.
+ * @param[in] label Optional label L to be associated with the message.
+ * @retval ESYS_RC_SUCCESS if the function call was a success.
+ * @retval TSS2_ESYS_RC_BAD_REFERENCE if the esysContext or required input
+ * pointers or required output handle references are NULL.
+ * @retval TSS2_ESYS_RC_BAD_CONTEXT: if esysContext corruption is detected.
+ * @retval TSS2_ESYS_RC_MEMORY: if the ESAPI cannot allocate enough memory for
+ * internal operations or return parameters.
+ * @retval TSS2_RCs produced by lower layers of the software stack may be
+ returned to the caller unaltered unless handled internally.
+ * @retval TSS2_ESYS_RC_MULTIPLE_DECRYPT_SESSIONS: if more than one session has
+ * the 'decrypt' attribute bit set.
+ * @retval TSS2_ESYS_RC_MULTIPLE_ENCRYPT_SESSIONS: if more than one session has
+ * the 'encrypt' attribute bit set.
+ * @retval TSS2_ESYS_RC_BAD_TR: if any of the ESYS_TR objects are unknown
+ * to the ESYS_CONTEXT or are of the wrong type or if required
+ * ESYS_TR objects are ESYS_TR_NONE.
+ */
+TSS2_RC
+Esys_ECC_Encrypt_Async(
+ ESYS_CONTEXT *esysContext,
+ ESYS_TR keyHandle,
+ ESYS_TR shandle1,
+ ESYS_TR shandle2,
+ ESYS_TR shandle3,
+ const TPMT_ECC_DECRYPT *inScheme,
+ const TPM2B_MAX_BUFFER *message,
+ const TPM2B_DATA *sharedData1,
+ const TPM2B_DATA *sharedData2)
+{
+ TSS2_RC r;
+ LOG_TRACE("context=%p, keyHandle=%"PRIx32 ", message=%p,"
+ "inScheme=%p, sharedData1=%p, sharedData2=%p",
+ esysContext, keyHandle, message, inScheme, sharedData1, sharedData2);
+ TSS2L_SYS_AUTH_COMMAND auths;
+ RSRC_NODE_T *keyHandleNode;
+
+ /* Check context, sequence correctness and set state to error for now */
+ if (esysContext == NULL) {
+ LOG_ERROR("esyscontext is NULL.");
+ return TSS2_ESYS_RC_BAD_REFERENCE;
+ }
+ r = iesys_check_sequence_async(esysContext);
+ if (r != TSS2_RC_SUCCESS)
+ return r;
+ esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+ /* Check input parameters */
+ r = check_session_feasibility(shandle1, shandle2, shandle3, 0);
+ return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
+
+ /* Retrieve the metadata objects for provided handles */
+ r = esys_GetResourceObject(esysContext, keyHandle, &keyHandleNode);
+ return_state_if_error(r, _ESYS_STATE_INIT, "keyHandle unknown.");
+
+ /* Initial invocation of SAPI to prepare the command buffer with parameters */
+ r = Tss2_Sys_ECC_Encrypt_Prepare(esysContext->sys,
+ (keyHandleNode == NULL) ? TPM2_RH_NULL
+ : keyHandleNode->rsrc.handle, inScheme,
+ message, sharedData1, sharedData2);
+ return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
+
+ /* Calculate the cpHash Values */
+ r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+ return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
+ iesys_compute_session_value(esysContext->session_tab[0], NULL, NULL);
+ iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
+ iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
+
+ /* Generate the auth values and set them in the SAPI command buffer */
+ r = iesys_gen_auths(esysContext, keyHandleNode, NULL, NULL, &auths);
+ return_state_if_error(r, _ESYS_STATE_INIT,
+ "Error in computation of auth values");
+
+ esysContext->authsCount = auths.count;
+ if (auths.count > 0) {
+ r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
+ return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
+ }
+
+ /* Trigger execution and finish the async invocation */
+ r = Tss2_Sys_ExecuteAsync(esysContext->sys);
+ return_state_if_error(r, _ESYS_STATE_INTERNALERROR,
+ "Finish (Execute Async)");
+
+ esysContext->state = _ESYS_STATE_SENT;
+
+ return r;
+}
+
+/** Asynchronous finish function for TPM2_ECC_Encrypt
+ *
+ * This function returns the results of a TPM2_ECC_Encrypt command
+ * invoked via Esys_ECC_Encrypt_Finish. All non-simple output parameters
+ * are allocated by the function's implementation. NULL can be passed for every
+ * output parameter if the value is not required.
+ *
+ * @param[in,out] esysContext The ESYS_CONTEXT.
+ * @param[out] outData Encrypted output.
+ * (callee-allocated)
+ * @retval TSS2_RC_SUCCESS on success
+ * @retval ESYS_RC_SUCCESS if the function call was a success.
+ * @retval TSS2_ESYS_RC_BAD_REFERENCE if the esysContext or required input
+ * pointers or required output handle references are NULL.
+ * @retval TSS2_ESYS_RC_BAD_CONTEXT: if esysContext corruption is detected.
+ * @retval TSS2_ESYS_RC_MEMORY: if the ESAPI cannot allocate enough memory for
+ * internal operations or return parameters.
+ * @retval TSS2_ESYS_RC_BAD_SEQUENCE: if the context has an asynchronous
+ * operation already pending.
+ * @retval TSS2_ESYS_RC_TRY_AGAIN: if the timeout counter expires before the
+ * TPM response is received.
+ * @retval TSS2_ESYS_RC_INSUFFICIENT_RESPONSE: if the TPM's response does not
+ * at least contain the tag, response length, and response code.
+ * @retval TSS2_ESYS_RC_RSP_AUTH_FAILED: if the response HMAC from the TPM did
+ * not verify.
+ * @retval TSS2_ESYS_RC_MALFORMED_RESPONSE: if the TPM's response is corrupted.
+ * @retval TSS2_RCs produced by lower layers of the software stack may be
+ * returned to the caller unaltered unless handled internally.
+ */
+TSS2_RC
+Esys_ECC_Encrypt_Finish(
+ ESYS_CONTEXT *esysContext,
+ TPM2B_MAX_BUFFER **outData)
+{
+ TSS2_RC r;
+ LOG_TRACE("context=%p, outData=%p",
+ esysContext, outData);
+
+ if (esysContext == NULL) {
+ LOG_ERROR("esyscontext is NULL.");
+ return TSS2_ESYS_RC_BAD_REFERENCE;
+ }
+
+ /* Check for correct sequence and set sequence to irregular for now */
+ if (esysContext->state != _ESYS_STATE_SENT &&
+ esysContext->state != _ESYS_STATE_RESUBMISSION) {
+ LOG_ERROR("Esys called in bad sequence.");
+ return TSS2_ESYS_RC_BAD_SEQUENCE;
+ }
+ esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+ /* Allocate memory for response parameters */
+ if (outData != NULL) {
+ *outData = calloc(sizeof(TPM2B_MAX_BUFFER), 1);
+ if (*outData == NULL) {
+ return_error(TSS2_ESYS_RC_MEMORY, "Out of memory");
+ }
+ }
+
+ /*Receive the TPM response and handle resubmissions if necessary. */
+ r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
+ if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
+ LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+ esysContext->state = _ESYS_STATE_SENT;
+ goto error_cleanup;
+ }
+ /* This block handle the resubmission of TPM commands given a certain set of
+ * TPM response codes. */
+ if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
+ LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
+ "resubmission: %" PRIx32, r);
+ if (esysContext->submissionCount++ >= _ESYS_MAX_SUBMISSIONS) {
+ LOG_WARNING("Maximum number of (re)submissions has been reached.");
+ esysContext->state = _ESYS_STATE_INIT;
+ goto error_cleanup;
+ }
+ esysContext->state = _ESYS_STATE_RESUBMISSION;
+ r = Tss2_Sys_ExecuteAsync(esysContext->sys);
+ if (r != TSS2_RC_SUCCESS) {
+ LOG_WARNING("Error attempting to resubmit");
+ /* We do not set esysContext->state here but inherit the most recent
+ * state of the _async function. */
+ goto error_cleanup;
+ }
+ r = TSS2_ESYS_RC_TRY_AGAIN;
+ LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
+ goto error_cleanup;
+ }
+ /* The following is the "regular error" handling. */
+ if (iesys_tpm_error(r)) {
+ LOG_WARNING("Received TPM Error");
+ esysContext->state = _ESYS_STATE_INIT;
+ goto error_cleanup;
+ } else if (r != TSS2_RC_SUCCESS) {
+ LOG_ERROR("Received a non-TPM Error");
+ esysContext->state = _ESYS_STATE_INTERNALERROR;
+ goto error_cleanup;
+ }
+
+ /*
+ * Now the verification of the response (hmac check) and if necessary the
+ * parameter decryption have to be done.
+ */
+ r = iesys_check_response(esysContext);
+ goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response",
+ error_cleanup);
+
+ /*
+ * After the verification of the response we call the complete function
+ * to deliver the result.
+ */
+ r = Tss2_Sys_ECC_Encrypt_Complete(esysContext->sys,
+ (outData != NULL) ? *outData : NULL);
+ goto_state_if_error(r, _ESYS_STATE_INTERNALERROR,
+ "Received error from SAPI unmarshaling" ,
+ error_cleanup);
+
+ esysContext->state = _ESYS_STATE_INIT;
+
+ return TSS2_RC_SUCCESS;
+
+error_cleanup:
+ if (outData != NULL)
+ SAFE_FREE(*outData);
+
+ return r;
+}
diff --git a/src/tss2-mu/tpmt-types.c b/src/tss2-mu/tpmt-types.c
index df899a6..41cdf36 100644
--- a/src/tss2-mu/tpmt-types.c
+++ b/src/tss2-mu/tpmt-types.c
@@ -552,6 +552,12 @@ TPMT_MARSHAL_2(TPMT_RSA_DECRYPT, scheme, VAL, Tss2_MU_UINT16_Marshal,
TPMT_UNMARSHAL_2(TPMT_RSA_DECRYPT, scheme, Tss2_MU_UINT16_Unmarshal,
details, scheme, Tss2_MU_TPMU_ASYM_SCHEME_Unmarshal)
+TPMT_MARSHAL_2(TPMT_ECC_DECRYPT, scheme, VAL, Tss2_MU_UINT16_Marshal,
+ details, ADDR, scheme, Tss2_MU_TPMU_ASYM_SCHEME_Marshal)
+
+TPMT_UNMARSHAL_2(TPMT_ECC_DECRYPT, scheme, Tss2_MU_UINT16_Unmarshal,
+ details, scheme, Tss2_MU_TPMU_ASYM_SCHEME_Unmarshal)
+
TPMT_MARSHAL_2(TPMT_ECC_SCHEME, scheme, VAL, Tss2_MU_UINT16_Marshal,
details, ADDR, scheme, Tss2_MU_TPMU_ASYM_SCHEME_Marshal)
diff --git a/src/tss2-sys/api/Tss2_Sys_ECC_Decrypt.c b/src/tss2-sys/api/Tss2_Sys_ECC_Decrypt.c
new file mode 100644
index 0000000..9f6a596
--- /dev/null
+++ b/src/tss2-sys/api/Tss2_Sys_ECC_Decrypt.c
@@ -0,0 +1,153 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+/***********************************************************************;
+ * Copyright (c) 2015 - 2017, Intel Corporation
+ * All rights reserved.
+ ***********************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "tss2_tpm2_types.h"
+#include "tss2_mu.h"
+#include "sysapi_util.h"
+
+TSS2_RC Tss2_Sys_ECC_Decrypt_Prepare(
+ TSS2_SYS_CONTEXT *sysContext,
+ TPMI_DH_OBJECT keyHandle,
+ const TPMT_ECC_DECRYPT *inScheme,
+ const TPM2B_MAX_BUFFER *cipherText,
+ const TPM2B_DATA *sharedData1,
+ const TPM2B_DATA *sharedData2)
+{
+ _TSS2_SYS_CONTEXT_BLOB *ctx = syscontext_cast(sysContext);
+ TSS2_RC rval;
+
+ if (!ctx || !inScheme)
+ return TSS2_SYS_RC_BAD_REFERENCE;
+
+ rval = CommonPreparePrologue(ctx, TPM2_CC_ECC_Decrypt);
+ if (rval)
+ return rval;
+
+ rval = Tss2_MU_UINT32_Marshal(keyHandle, ctx->cmdBuffer,
+ ctx->maxCmdSize,
+ &ctx->nextData);
+ if (rval)
+ return rval;
+
+ /* Encryption is not possible because the exchange of parameter inScheme
+ and cipherText in tcm2.0 spec. so disable decryptAllowed in the following code.
+ */
+ rval = Tss2_MU_TPMT_ECC_DECRYPT_Marshal(inScheme, ctx->cmdBuffer,
+ ctx->maxCmdSize,
+ &ctx->nextData);
+ if (rval)
+ return rval;
+
+ if (!cipherText) {
+ ctx->decryptNull = 1;
+
+ rval = Tss2_MU_UINT16_Marshal(0, ctx->cmdBuffer,
+ ctx->maxCmdSize,
+ &ctx->nextData);
+ } else {
+
+ rval = Tss2_MU_TPM2B_MAX_BUFFER_Marshal(cipherText, ctx->cmdBuffer,
+ ctx->maxCmdSize,
+ &ctx->nextData);
+ }
+
+ if (rval)
+ return rval;
+
+#if 0
+ rval = Tss2_MU_TPMT_ECC_DECRYPT_Marshal(inScheme, ctx->cmdBuffer,
+ ctx->maxCmdSize,
+ &ctx->nextData);
+ if (rval)
+ return rval;
+#endif
+
+ if (!sharedData1) {
+ rval = Tss2_MU_UINT16_Marshal(0, ctx->cmdBuffer,
+ ctx->maxCmdSize,
+ &ctx->nextData);
+
+ } else {
+
+ rval = Tss2_MU_TPM2B_DATA_Marshal(sharedData1, ctx->cmdBuffer,
+ ctx->maxCmdSize,
+ &ctx->nextData);
+ }
+ if (rval)
+ return rval;
+
+ if (!sharedData2) {
+ rval = Tss2_MU_UINT16_Marshal(0, ctx->cmdBuffer,
+ ctx->maxCmdSize,
+ &ctx->nextData);
+
+ } else {
+
+ rval = Tss2_MU_TPM2B_DATA_Marshal(sharedData2, ctx->cmdBuffer,
+ ctx->maxCmdSize,
+ &ctx->nextData);
+ }
+ if (rval)
+ return rval;
+
+ //ctx->decryptAllowed = 1;
+ ctx->decryptAllowed = 0;
+ ctx->encryptAllowed = 1;
+ ctx->authAllowed = 1;
+
+ return CommonPrepareEpilogue(ctx);
+}
+
+TSS2_RC Tss2_Sys_ECC_Decrypt_Complete(
+ TSS2_SYS_CONTEXT *sysContext,
+ TPM2B_MAX_BUFFER *outData)
+{
+ _TSS2_SYS_CONTEXT_BLOB *ctx = syscontext_cast(sysContext);
+ TSS2_RC rval;
+
+ if (!ctx)
+ return TSS2_SYS_RC_BAD_REFERENCE;
+
+ rval = CommonComplete(ctx);
+ if (rval)
+ return rval;
+
+ return Tss2_MU_TPM2B_MAX_BUFFER_Unmarshal(ctx->cmdBuffer,
+ ctx->maxCmdSize,
+ &ctx->nextData, outData);
+}
+
+TSS2_RC Tss2_Sys_ECC_Decrypt(
+ TSS2_SYS_CONTEXT *sysContext,
+ TPMI_DH_OBJECT keyHandle,
+ TSS2L_SYS_AUTH_COMMAND const *cmdAuthsArray,
+ const TPMT_ECC_DECRYPT *inScheme,
+ const TPM2B_MAX_BUFFER *message,
+ const TPM2B_DATA *sharedData1,
+ const TPM2B_DATA *sharedData2,
+ TPM2B_MAX_BUFFER *outData,
+ TSS2L_SYS_AUTH_RESPONSE *rspAuthsArray)
+{
+ _TSS2_SYS_CONTEXT_BLOB *ctx = syscontext_cast(sysContext);
+ TSS2_RC rval;
+
+ if (!inScheme)
+ return TSS2_SYS_RC_BAD_REFERENCE;
+
+ rval = Tss2_Sys_ECC_Decrypt_Prepare(sysContext, keyHandle, inScheme, message, sharedData1, sharedData2);
+ if (rval)
+ return rval;
+
+ rval = CommonOneCall(ctx, cmdAuthsArray, rspAuthsArray);
+ if (rval)
+ return rval;
+
+ return Tss2_Sys_ECC_Decrypt_Complete(sysContext, outData);
+}
diff --git a/src/tss2-sys/api/Tss2_Sys_ECC_Encrypt.c b/src/tss2-sys/api/Tss2_Sys_ECC_Encrypt.c
new file mode 100644
index 0000000..af02d4c
--- /dev/null
+++ b/src/tss2-sys/api/Tss2_Sys_ECC_Encrypt.c
@@ -0,0 +1,153 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+/***********************************************************************;
+ * Copyright (c) 2015 - 2017, Intel Corporation
+ * All rights reserved.
+ ***********************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "tss2_tpm2_types.h"
+#include "tss2_mu.h"
+#include "sysapi_util.h"
+
+TSS2_RC Tss2_Sys_ECC_Encrypt_Prepare(
+ TSS2_SYS_CONTEXT *sysContext,
+ TPMI_DH_OBJECT keyHandle,
+ const TPMT_ECC_DECRYPT *inScheme,
+ const TPM2B_MAX_BUFFER *message,
+ const TPM2B_DATA *sharedData1,
+ const TPM2B_DATA *sharedData2)
+{
+ _TSS2_SYS_CONTEXT_BLOB *ctx = syscontext_cast(sysContext);
+ TSS2_RC rval;
+
+ if (!ctx || !inScheme)
+ return TSS2_SYS_RC_BAD_REFERENCE;
+
+ rval = CommonPreparePrologue(ctx, TPM2_CC_ECC_Encrypt);
+ if (rval)
+ return rval;
+
+ rval = Tss2_MU_UINT32_Marshal(keyHandle, ctx->cmdBuffer,
+ ctx->maxCmdSize,
+ &ctx->nextData);
+ if (rval)
+ return rval;
+
+ /* Encryption is not possible because the exchange of parameter inScheme
+ and message in tcm2.0 spec. so disable decryptAllowed in the following code.
+ */
+ rval = Tss2_MU_TPMT_ECC_DECRYPT_Marshal(inScheme, ctx->cmdBuffer,
+ ctx->maxCmdSize,
+ &ctx->nextData);
+ if (rval)
+ return rval;
+
+ if (!message) {
+ ctx->decryptNull = 1;
+
+ rval = Tss2_MU_UINT16_Marshal(0, ctx->cmdBuffer,
+ ctx->maxCmdSize,
+ &ctx->nextData);
+ } else {
+
+ rval = Tss2_MU_TPM2B_MAX_BUFFER_Marshal(message, ctx->cmdBuffer,
+ ctx->maxCmdSize,
+ &ctx->nextData);
+ }
+
+ if (rval)
+ return rval;
+
+#if 0
+ rval = Tss2_MU_TPMT_ECC_DECRYPT_Marshal(inScheme, ctx->cmdBuffer,
+ ctx->maxCmdSize,
+ &ctx->nextData);
+ if (rval)
+ return rval;
+#endif
+
+ if (!sharedData1) {
+ rval = Tss2_MU_UINT16_Marshal(0, ctx->cmdBuffer,
+ ctx->maxCmdSize,
+ &ctx->nextData);
+
+ } else {
+
+ rval = Tss2_MU_TPM2B_DATA_Marshal(sharedData1, ctx->cmdBuffer,
+ ctx->maxCmdSize,
+ &ctx->nextData);
+ }
+ if (rval)
+ return rval;
+
+ if (!sharedData2) {
+ rval = Tss2_MU_UINT16_Marshal(0, ctx->cmdBuffer,
+ ctx->maxCmdSize,
+ &ctx->nextData);
+
+ } else {
+
+ rval = Tss2_MU_TPM2B_DATA_Marshal(sharedData2, ctx->cmdBuffer,
+ ctx->maxCmdSize,
+ &ctx->nextData);
+ }
+ if (rval)
+ return rval;
+
+ //ctx->decryptAllowed = 1;
+ ctx->decryptAllowed = 0;
+ ctx->encryptAllowed = 1;
+ ctx->authAllowed = 1;
+
+ return CommonPrepareEpilogue(ctx);
+}
+
+TSS2_RC Tss2_Sys_ECC_Encrypt_Complete(
+ TSS2_SYS_CONTEXT *sysContext,
+ TPM2B_MAX_BUFFER *outData)
+{
+ _TSS2_SYS_CONTEXT_BLOB *ctx = syscontext_cast(sysContext);
+ TSS2_RC rval;
+
+ if (!ctx)
+ return TSS2_SYS_RC_BAD_REFERENCE;
+
+ rval = CommonComplete(ctx);
+ if (rval)
+ return rval;
+
+ return Tss2_MU_TPM2B_MAX_BUFFER_Unmarshal(ctx->cmdBuffer,
+ ctx->maxCmdSize,
+ &ctx->nextData, outData);
+}
+
+TSS2_RC Tss2_Sys_ECC_Encrypt(
+ TSS2_SYS_CONTEXT *sysContext,
+ TPMI_DH_OBJECT keyHandle,
+ TSS2L_SYS_AUTH_COMMAND const *cmdAuthsArray,
+ const TPMT_ECC_DECRYPT *inScheme,
+ const TPM2B_MAX_BUFFER *message,
+ const TPM2B_DATA *sharedData1,
+ const TPM2B_DATA *sharedData2,
+ TPM2B_MAX_BUFFER *outData,
+ TSS2L_SYS_AUTH_RESPONSE *rspAuthsArray)
+{
+ _TSS2_SYS_CONTEXT_BLOB *ctx = syscontext_cast(sysContext);
+ TSS2_RC rval;
+
+ if (!inScheme)
+ return TSS2_SYS_RC_BAD_REFERENCE;
+
+ rval = Tss2_Sys_ECC_Encrypt_Prepare(sysContext, keyHandle, inScheme, message, sharedData1, sharedData2);
+ if (rval)
+ return rval;
+
+ rval = CommonOneCall(ctx, cmdAuthsArray, rspAuthsArray);
+ if (rval)
+ return rval;
+
+ return Tss2_Sys_ECC_Encrypt_Complete(sysContext, outData);
+}
diff --git a/src/tss2-sys/sysapi_util.c b/src/tss2-sys/sysapi_util.c
index 6e59da0..9824824 100644
--- a/src/tss2-sys/sysapi_util.c
+++ b/src/tss2-sys/sysapi_util.c
@@ -288,7 +288,9 @@ static int GetNumHandles(TPM2_CC commandCode, bool req)
{ TPM2_CC_AC_Send, 3, 0 },
{ TPM2_CC_Policy_AC_SendSelect, 1, 0 },
{ TPM2_CC_ACT_SetTimeout, 1, 0 },
- { TPM2_CC_CertifyX509, 2, 0 }
+ { TPM2_CC_CertifyX509, 2, 0 },
+ { TPM2_CC_ECC_Encrypt, 1, 0 },
+ { TPM2_CC_ECC_Decrypt, 1, 0 }
};
uint8_t i;
--
2.17.1
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。