2121#include "tss2_common.h" // for TSS2_RC, BYTE, TSS2_RC_SUCCESS, TSS2_BA...
2222#include "tss2_esys.h" // for Esys_SetTimeout, ESYS_TR_NONE, Esys_Flu...
2323#include "tss2_fapi.h" // for FAPI_CONTEXT, Fapi_Decrypt, Fapi_Decryp...
24+ #include "tss2_mu.h" // for unmarshaling of encrypted ecc data.
2425#include "tss2_tcti.h" // for TSS2_TCTI_TIMEOUT_BLOCK
2526#include "tss2_tpm2_types.h" // for TPM2B_PUBLIC_KEY_RSA, TPM2B_PUBLIC, TPM...
2627
2728#define LOGMODULE fapi
2829#include "util/log.h" // for SAFE_FREE, LOG_TRACE, goto_if_error
2930
31+ static TPM2_RC
32+ unmarshal_ecc_crypt_result (const uint8_t * crypt_buf ,
33+ size_t size_crypt_buf ,
34+ TPM2B_ECC_POINT * c1 ,
35+ TPM2B_MAX_BUFFER * c2 ,
36+ TPM2B_DIGEST * c3 ) {
37+ TSS2_RC rc ;
38+ size_t pos = 0 ;
39+ size_t offset = 0 ;
40+
41+ rc = Tss2_MU_TPM2B_ECC_POINT_Unmarshal (& crypt_buf [pos ], size_crypt_buf , & offset , c1 );
42+ return_if_error (rc , "Unmarshal Point." );
43+
44+ pos += offset ;
45+ offset = 0 ;
46+ rc = Tss2_MU_TPM2B_MAX_BUFFER_Unmarshal (& crypt_buf [pos ], size_crypt_buf , & offset , c2 );
47+ return_if_error (rc , "Unmarshal Max Buffer." );
48+
49+ pos += offset ;
50+ offset = 0 ;
51+ rc = Tss2_MU_TPM2B_DIGEST_Unmarshal (& crypt_buf [pos ], size_crypt_buf , & offset , c3 );
52+ return_if_error (rc , "Unmarshal Digest." );
53+
54+ return rc ;
55+ }
56+
3057/** One-Call function for Fapi_Decrypt
3158 *
3259 * Decrypts data that was previously encrypted with Fapi_Encrypt.
@@ -242,6 +269,7 @@ Fapi_Decrypt_Finish(FAPI_CONTEXT *context, uint8_t **plainText, size_t *plainTex
242269
243270 TSS2_RC r ;
244271 TPM2B_PUBLIC_KEY_RSA * tpmPlainText = NULL ;
272+ TPM2B_MAX_BUFFER * ecc_plain_text ;
245273
246274 /* Check for NULL parameters */
247275 check_not_null (context );
@@ -297,6 +325,12 @@ Fapi_Decrypt_Finish(FAPI_CONTEXT *context, uint8_t **plainText, size_t *plainTex
297325 r = ifapi_authorize_object (context , command -> key_object , & command -> auth_session );
298326 return_try_again (r );
299327 goto_if_error (r , "Authorize key." , error_cleanup );
328+
329+ if (command -> key_object -> misc .key .public .publicArea .type == TPM2_ALG_ECC ) {
330+ context -> state = DATA_DECRYPT_PREPARE_ECC_ENCRYPTION ;
331+ return TSS2_FAPI_RC_TRY_AGAIN ;
332+ }
333+
300334 TPM2B_DATA null_data = { .size = 0 , .buffer = {} };
301335
302336 /* Copy cipher data to tpm object */
@@ -319,15 +353,17 @@ Fapi_Decrypt_Finish(FAPI_CONTEXT *context, uint8_t **plainText, size_t *plainTex
319353 goto_if_error_reset_state (r , "RSA decryption." , error_cleanup );
320354
321355 /* Duplicate the decrypted plaintext for returning to the user. */
322- if (plainTextSize )
323- command -> plainTextSize = tpmPlainText -> size ;
324356 if (plainText ) {
357+ command -> plainTextSize = tpmPlainText -> size ;
325358 command -> plainText = malloc (tpmPlainText -> size );
326359 goto_if_null (command -> plainText , "Out of memory" , TSS2_FAPI_RC_MEMORY , error_cleanup );
327360
328361 memcpy (command -> plainText , & tpmPlainText -> buffer [0 ], tpmPlainText -> size );
329362 SAFE_FREE (tpmPlainText );
330363 }
364+ fallthrough ;
365+
366+ statecase (context -> state , DATA_DECRYPT_PREPARE_FLUSH );
331367
332368 /* Flush the used key. */
333369 if (!command -> key_object -> misc .key .persistent_handle ) {
@@ -358,6 +394,37 @@ Fapi_Decrypt_Finish(FAPI_CONTEXT *context, uint8_t **plainText, size_t *plainTex
358394 * plainTextSize = command -> plainTextSize ;
359395 break ;
360396
397+ statecase (context -> state , DATA_DECRYPT_PREPARE_ECC_ENCRYPTION )
398+ /* Decrypt the actual data. */
399+ TPM2B_ECC_POINT c1 ;
400+ TPM2B_MAX_BUFFER c2 ;
401+ TPM2B_DIGEST c3 ;
402+
403+ r = unmarshal_ecc_crypt_result (command -> in_data , command -> numBytes , & c1 , & c2 , & c3 );
404+ goto_if_error (r , "Unmarshal ECC cipher" , error_cleanup );
405+
406+ r = Esys_ECC_Decrypt_Async (context -> esys , context -> cmd .Data_EncryptDecrypt .key_handle ,
407+ command -> auth_session ,
408+ ENC_SESSION_IF_POLICY (command -> auth_session ), ESYS_TR_NONE , & c1 ,
409+ & c2 , & c3 , & command -> profile -> ecc_crypt_scheme );
410+ goto_if_error (r , "Error esys rsa decrypt" , error_cleanup );
411+ fallthrough ;
412+
413+ statecase (context -> state , DATA_DECRYPT_WAIT_FOR_ECC_DECRYPTION );
414+ r = Esys_ECC_Decrypt_Finish (context -> esys , & ecc_plain_text );
415+ return_try_again (r );
416+ goto_if_error_reset_state (r , "ECC decryption." , error_cleanup );
417+ if (ecc_plain_text ) {
418+ command -> plainTextSize = ecc_plain_text -> size ;
419+ command -> plainText = malloc (ecc_plain_text -> size );
420+ goto_if_null (command -> plainText , "Out of memory" , TSS2_FAPI_RC_MEMORY , error_cleanup );
421+
422+ memcpy (command -> plainText , & ecc_plain_text -> buffer [0 ], ecc_plain_text -> size );
423+ SAFE_FREE (ecc_plain_text );
424+ }
425+ context -> state = DATA_DECRYPT_PREPARE_FLUSH ;
426+ return TSS2_FAPI_RC_TRY_AGAIN ;
427+
361428 statecasedefault (context -> state );
362429 }
363430
0 commit comments