77use std:: { ffi:: c_char, fmt:: Display , num:: NonZeroUsize , os:: raw:: c_void, ptr, sync:: RwLock } ;
88
99use crate :: {
10- BaseErrorCode , BlobType , ErrorCode , FapiCallbacks , ImportData , InternalError , KeyFlags , NvFlags , PaddingFlags , QuoteFlags , QuoteResult , SealFlags ,
11- SignResult , TpmBlobs ,
10+ BaseErrorCode , BlobType , ErrorCode , FapiCallbacks , ImportData , InternalError , KeyFlags , NvFlags , PaddingFlags , QuoteFlags , QuoteResult , SealData ,
11+ SealFlags , SignResult , TpmBlobs ,
1212 callback:: { CallbackManager , entry_point} ,
1313 fapi_sys:: { self , FAPI_CONTEXT , TPM2_RC , TSS2_RC , constants:: TSS2_RC_SUCCESS } ,
1414 flags:: Flags ,
1515 json:: { self , JsonValue } ,
1616 locking:: LockGuard ,
1717 marshal:: u64_from_be,
18- memory:: { CStringHolder , FapiMemoryHolder , cond_out, cond_ptr, opt_to_len , opt_to_ptr } ,
18+ memory:: { CBinaryHolder , CStringHolder , FapiMemoryHolder , cond_out, cond_ptr} ,
1919} ;
2020
2121/* Const */
2222const ERR_NO_RESULT_DATA : ErrorCode = ErrorCode :: InternalError ( InternalError :: NoResultData ) ;
2323const ERR_INVALID_ARGUMENTS : ErrorCode = ErrorCode :: InternalError ( InternalError :: InvalidArguments ) ;
2424
25- /* Opaque type */
26- type TctiOpaqueContextBlob = * mut [ u8 ; 0 ] ;
25+ /* Opaque ContextBlob type */
26+ #[ derive( Debug ) ]
27+ pub struct TctiOpaqueContextBlob ( pub * mut c_void ) ;
2728
2829/// Wraps the native `FAPI_CONTEXT` and exposes the related FAPI functions.
2930///
@@ -402,8 +403,9 @@ impl FapiContext {
402403 pub fn nv_write ( & mut self , nv_path : & str , data : & [ u8 ] ) -> Result < ( ) , ErrorCode > {
403404 fail_if_empty ! ( data) ;
404405 let cstr_path = CStringHolder :: try_from ( nv_path) ?;
406+ let cstr_data = CBinaryHolder :: try_from ( data) ?;
405407
406- self . fapi_call ( false , |context| unsafe { fapi_sys:: Fapi_NvWrite ( context, cstr_path. as_ptr ( ) , data . as_ptr ( ) , data . len ( ) ) } )
408+ self . fapi_call ( false , |context| unsafe { fapi_sys:: Fapi_NvWrite ( context, cstr_path. as_ptr ( ) , cstr_data . as_ptr ( ) , cstr_data . len ( ) ) } )
407409 }
408410
409411 /// Convenience function to [`nv_write()`](FapiContext::nv_write) an **`u64`** value. Assumes "big endian" byte order.
@@ -439,8 +441,11 @@ impl FapiContext {
439441
440442 let cstr_path = CStringHolder :: try_from ( nv_path) ?;
441443 let cstr_logs = CStringHolder :: try_from ( log_data) ?;
444+ let cstr_data = CBinaryHolder :: try_from ( data) ?;
442445
443- self . fapi_call ( false , |context| unsafe { fapi_sys:: Fapi_NvExtend ( context, cstr_path. as_ptr ( ) , data. as_ptr ( ) , data. len ( ) , cstr_logs. as_ptr ( ) ) } )
446+ self . fapi_call ( false , |context| unsafe {
447+ fapi_sys:: Fapi_NvExtend ( context, cstr_path. as_ptr ( ) , cstr_data. as_ptr ( ) , cstr_data. len ( ) , cstr_logs. as_ptr ( ) )
448+ } )
444449 }
445450
446451 /// Write the policyDigest of a policy to an NV index so it can be used in policies containing PolicyAuthorizeNV elements.
@@ -463,9 +468,10 @@ impl FapiContext {
463468 pub fn pcr_extend ( & mut self , pcr_no : u32 , data : & [ u8 ] , log_data : Option < & str > ) -> Result < ( ) , ErrorCode > {
464469 fail_if_empty ! ( data) ;
465470
471+ let cstr_data = CBinaryHolder :: try_from ( data) ?;
466472 let cstr_logs = CStringHolder :: try_from ( log_data) ?;
467473
468- self . fapi_call ( false , |context| unsafe { fapi_sys:: Fapi_PcrExtend ( context, pcr_no, data . as_ptr ( ) , data . len ( ) , cstr_logs. as_ptr ( ) ) } )
474+ self . fapi_call ( false , |context| unsafe { fapi_sys:: Fapi_PcrExtend ( context, pcr_no, cstr_data . as_ptr ( ) , cstr_data . len ( ) , cstr_logs. as_ptr ( ) ) } )
469475 }
470476
471477 /// Reads from a given PCR and returns the value and the event log.
@@ -508,6 +514,7 @@ impl FapiContext {
508514
509515 let cstr_path = CStringHolder :: try_from ( key_path) ?;
510516 let cstr_type = CStringHolder :: try_from ( Flags :: as_string ( quote_type) ?) ?;
517+ let cstr_qual = CBinaryHolder :: try_from ( qualifying_data) ?;
511518
512519 let mut quote_info: * mut c_char = ptr:: null_mut ( ) ;
513520 let mut signature_data: * mut u8 = ptr:: null_mut ( ) ;
@@ -522,8 +529,8 @@ impl FapiContext {
522529 pcr_no. len ( ) ,
523530 cstr_path. as_ptr ( ) ,
524531 cstr_type. as_ptr ( ) ,
525- opt_to_ptr ( qualifying_data ) ,
526- opt_to_len ( qualifying_data ) ,
532+ cstr_qual . as_ptr ( ) ,
533+ cstr_qual . len ( ) ,
527534 & mut quote_info,
528535 & mut signature_data,
529536 & mut signature_size,
@@ -557,16 +564,18 @@ impl FapiContext {
557564 let cstr_path = CStringHolder :: try_from ( key_path) ?;
558565 let cstr_info = CStringHolder :: try_from ( quote_info) ?;
559566 let cstr_logs = CStringHolder :: try_from ( prc_log) ?;
567+ let cstr_qual = CBinaryHolder :: try_from ( qualifying_data) ?;
568+ let cstr_sign = CBinaryHolder :: try_from ( signature) ?;
560569
561570 self . fapi_call ( false , |context| unsafe {
562571 fapi_sys:: Fapi_VerifyQuote (
563572 context,
564573 cstr_path. as_ptr ( ) ,
565- opt_to_ptr ( qualifying_data ) ,
566- opt_to_len ( qualifying_data ) ,
574+ cstr_qual . as_ptr ( ) ,
575+ cstr_qual . len ( ) ,
567576 cstr_info. as_ptr ( ) ,
568- signature . as_ptr ( ) ,
569- signature . len ( ) ,
577+ cstr_sign . as_ptr ( ) ,
578+ cstr_sign . len ( ) ,
570579 cstr_logs. as_ptr ( ) ,
571580 )
572581 } )
@@ -589,12 +598,13 @@ impl FapiContext {
589598 fail_if_empty ! ( plaintext) ;
590599
591600 let cstr_path = CStringHolder :: try_from ( key_path) ?;
601+ let cstr_plaintext = CBinaryHolder :: try_from ( plaintext) ?;
592602
593603 let mut ciphertext_data: * mut u8 = ptr:: null_mut ( ) ;
594604 let mut ciphertext_size: usize = 0 ;
595605
596606 self . fapi_call ( false , |context| unsafe {
597- fapi_sys:: Fapi_Encrypt ( context, cstr_path. as_ptr ( ) , plaintext . as_ptr ( ) , plaintext . len ( ) , & mut ciphertext_data, & mut ciphertext_size)
607+ fapi_sys:: Fapi_Encrypt ( context, cstr_path. as_ptr ( ) , cstr_plaintext . as_ptr ( ) , cstr_plaintext . len ( ) , & mut ciphertext_data, & mut ciphertext_size)
598608 } )
599609 . and_then ( |_| FapiMemoryHolder :: from_raw ( ciphertext_data, ciphertext_size) . to_vec ( ) . ok_or ( ERR_NO_RESULT_DATA ) )
600610 }
@@ -606,12 +616,13 @@ impl FapiContext {
606616 fail_if_empty ! ( ciphertext) ;
607617
608618 let cstr_path = CStringHolder :: try_from ( key_path) ?;
619+ let cstr_ciphertext = CBinaryHolder :: try_from ( ciphertext) ?;
609620
610621 let mut plaintext_data: * mut u8 = ptr:: null_mut ( ) ;
611622 let mut plaintext_size: usize = 0 ;
612623
613624 self . fapi_call ( false , |context| unsafe {
614- fapi_sys:: Fapi_Decrypt ( context, cstr_path. as_ptr ( ) , ciphertext . as_ptr ( ) , ciphertext . len ( ) , & mut plaintext_data, & mut plaintext_size)
625+ fapi_sys:: Fapi_Decrypt ( context, cstr_path. as_ptr ( ) , cstr_ciphertext . as_ptr ( ) , cstr_ciphertext . len ( ) , & mut plaintext_data, & mut plaintext_size)
615626 } )
616627 . and_then ( |_| FapiMemoryHolder :: from_raw ( plaintext_data, plaintext_size) . to_vec ( ) . ok_or ( ERR_NO_RESULT_DATA ) )
617628 }
@@ -639,6 +650,7 @@ impl FapiContext {
639650
640651 let cstr_path = CStringHolder :: try_from ( key_path) ?;
641652 let cstr_algo = CStringHolder :: try_from ( Flags :: as_string ( pad_algo) ?) ?;
653+ let cstr_hash = CBinaryHolder :: try_from ( digest) ?;
642654
643655 let mut signature_data: * mut u8 = ptr:: null_mut ( ) ;
644656 let mut signature_size: usize = 0 ;
@@ -650,8 +662,8 @@ impl FapiContext {
650662 context,
651663 cstr_path. as_ptr ( ) ,
652664 cstr_algo. as_ptr ( ) ,
653- digest . as_ptr ( ) ,
654- digest . len ( ) ,
665+ cstr_hash . as_ptr ( ) ,
666+ cstr_hash . len ( ) ,
655667 & mut signature_data,
656668 & mut signature_size,
657669 cond_out ( & mut public_key_pem, get_pubkey) ,
@@ -673,9 +685,11 @@ impl FapiContext {
673685 fail_if_empty ! ( digest, signature) ;
674686
675687 let cstr_path = CStringHolder :: try_from ( key_path) ?;
688+ let cstr_hash = CBinaryHolder :: try_from ( digest) ?;
689+ let cstr_sign = CBinaryHolder :: try_from ( signature) ?;
676690
677691 self . fapi_call ( false , |context| unsafe {
678- fapi_sys:: Fapi_VerifySignature ( context, cstr_path. as_ptr ( ) , digest . as_ptr ( ) , digest . len ( ) , signature . as_ptr ( ) , signature . len ( ) )
692+ fapi_sys:: Fapi_VerifySignature ( context, cstr_path. as_ptr ( ) , cstr_hash . as_ptr ( ) , cstr_hash . len ( ) , cstr_sign . as_ptr ( ) , cstr_sign . len ( ) )
679693 } )
680694 . map ( |_| true )
681695 . or_else ( |error| match error {
@@ -689,25 +703,28 @@ impl FapiContext {
689703 // [ Sealing functions ]
690704 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
691705
692- /// Creates a sealed object and stores it in the FAPI metadata store. If no data is provided, the TPM generates random data to fill the sealed object.
706+ /// Creates a sealed object and stores it in the FAPI metadata store.
707+ ///
708+ /// The [`data`](crate::SealData) to be sealed can be given as a *non-empty* `&[u8]` slice. Alternatively, a [`NoneZeroUsize`](std::num::NonZeroUsize) size can be specified.
709+ ///
710+ /// If **no** explicit data is provided (i.e., only the size), the TPM generates random data to fill the sealed object.
693711 ///
694712 /// *See also:* [`Fapi_CreateSeal()`](https://tpm2-tss.readthedocs.io/en/stable/group___fapi___create_seal.html)
695713 pub fn create_seal (
696714 & mut self ,
697715 path : & str ,
698716 seal_type : Option < & [ SealFlags ] > ,
699- seal_size : NonZeroUsize ,
700717 pol_path : Option < & str > ,
701718 auth_val : Option < & str > ,
702- data : Option < & [ u8 ] > ,
719+ data : SealData ,
703720 ) -> Result < ( ) , ErrorCode > {
704721 fail_if_opt_empty ! ( seal_type) ;
705- fail_if_opt_empty ! ( data) ;
706722
707723 let cstr_path = CStringHolder :: try_from ( path) ?;
708724 let cstr_type = CStringHolder :: try_from ( Flags :: as_string ( seal_type) ?) ?;
709725 let cstr_poli = CStringHolder :: try_from ( pol_path) ?;
710726 let cstr_auth = CStringHolder :: try_from ( auth_val) ?;
727+ let ( seal_size, seal_data) = data. into_raw_data ( ) ?;
711728
712729 self . fapi_call ( false , |context| unsafe {
713730 fapi_sys:: Fapi_CreateSeal (
@@ -717,7 +734,7 @@ impl FapiContext {
717734 seal_size. get ( ) ,
718735 cstr_poli. as_ptr ( ) ,
719736 cstr_auth. as_ptr ( ) ,
720- opt_to_ptr ( data ) ,
737+ seal_data . as_ptr ( ) ,
721738 )
722739 } )
723740 }
@@ -827,8 +844,9 @@ impl FapiContext {
827844 pub fn set_app_data ( & mut self , path : & str , app_data : Option < & [ u8 ] > ) -> Result < ( ) , ErrorCode > {
828845 fail_if_opt_empty ! ( app_data) ;
829846 let cstr_path = CStringHolder :: try_from ( path) ?;
847+ let cstr_data = CBinaryHolder :: try_from ( app_data) ?;
830848
831- self . fapi_call ( false , |context| unsafe { fapi_sys:: Fapi_SetAppData ( context, cstr_path. as_ptr ( ) , opt_to_ptr ( app_data ) , opt_to_len ( app_data ) ) } )
849+ self . fapi_call ( false , |context| unsafe { fapi_sys:: Fapi_SetAppData ( context, cstr_path. as_ptr ( ) , cstr_data . as_ptr ( ) , cstr_data . len ( ) ) } )
832850 }
833851
834852 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -879,9 +897,10 @@ impl FapiContext {
879897
880898 let cstr_path_pol = CStringHolder :: try_from ( pol_path) ?;
881899 let cstr_path_key = CStringHolder :: try_from ( key_path) ?;
900+ let cstr_ref_data = CBinaryHolder :: try_from ( ref_data) ?;
882901
883902 self . fapi_call ( false , |context| unsafe {
884- fapi_sys:: Fapi_AuthorizePolicy ( context, cstr_path_pol. as_ptr ( ) , cstr_path_key. as_ptr ( ) , opt_to_ptr ( ref_data ) , opt_to_len ( ref_data ) )
903+ fapi_sys:: Fapi_AuthorizePolicy ( context, cstr_path_pol. as_ptr ( ) , cstr_path_key. as_ptr ( ) , cstr_ref_data . as_ptr ( ) , cstr_ref_data . len ( ) )
885904 } )
886905 }
887906
@@ -895,7 +914,7 @@ impl FapiContext {
895914 pub fn get_tcti ( & mut self ) -> Result < TctiOpaqueContextBlob , ErrorCode > {
896915 let mut tcti: * mut fapi_sys:: TSS2_TCTI_CONTEXT = ptr:: null_mut ( ) ;
897916
898- self . fapi_call ( false , |context| unsafe { fapi_sys:: Fapi_GetTcti ( context, & mut tcti) } ) . map ( |_| tcti as TctiOpaqueContextBlob )
917+ self . fapi_call ( false , |context| unsafe { fapi_sys:: Fapi_GetTcti ( context, & mut tcti) } ) . map ( |_| TctiOpaqueContextBlob ( tcti as * mut c_void ) )
899918 }
900919
901920 /// Returns an array of handles that can be polled on to get notified when data from the TPM or from a disk operation is available.
0 commit comments