Projects
Eulaceura:Mainline:GA
tpm2-tss
_service:obs_scm:Hygon-add-ecc-encrypt-decrypt-...
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File _service:obs_scm:Hygon-add-ecc-encrypt-decrypt-support.patch of Package tpm2-tss
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
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.
浙ICP备2022010568号-2