Skip to content

Commit

Permalink
treat errors in tpm functionality as fatal errors
Browse files Browse the repository at this point in the history
  • Loading branch information
neusdan committed Jun 14, 2015
1 parent 7410f16 commit d716a19
Show file tree
Hide file tree
Showing 6 changed files with 145 additions and 327 deletions.
97 changes: 34 additions & 63 deletions grub-core/kern/i386/pc/tpm/tpm_kern.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,11 +136,11 @@ tcg_statusCheck( grub_uint32_t* returnCode, grub_uint8_t* major, grub_uint8_t* m
*returnCode = args.out_eax;

if( *returnCode != TCG_PC_OK ) {
return grub_error( GRUB_ERR_TPM, N_( "tcg_statusCheck: asm_tcg_statusCheck failed: %x" ), *returnCode );
return grub_error( GRUB_ERR_TPM, N_( "tcg_statusCheck: asm_tcg_statusCheck failed: %x" ), *returnCode );
}

if( args.out_ebx != TCPA ) {
return grub_error( GRUB_ERR_TPM, N_( "tcg_statusCheck: asm_tcg_statusCheck failed: args.out_ebx != TCPA" ) );
grub_fatal( "tcg_statusCheck: asm_tcg_statusCheck failed: args.out_ebx != TCPA" );
}

*major = (grub_uint8_t) (args.out_ecx >> 8);
Expand All @@ -154,22 +154,21 @@ tcg_statusCheck( grub_uint32_t* returnCode, grub_uint8_t* major, grub_uint8_t* m

/* Invokes assembler function asm_tcg_passThroughToTPM()
Return value = 1 if function successfully completes
On error see returncode;
grub_fatal() on error
Page 112 TCG_PCClientImplementation_1-21_1_00
*/
grub_err_t
tcg_passThroughToTPM( const PassThroughToTPM_InputParamBlock* input, PassThroughToTPM_OutputParamBlock* output, grub_uint32_t* returnCode ) {
void
tcg_passThroughToTPM( const PassThroughToTPM_InputParamBlock* input, PassThroughToTPM_OutputParamBlock* output ) {

CHECK_FOR_NULL_ARGUMENT( input );
CHECK_FOR_NULL_ARGUMENT( output );

if( ! grub_TPM_isAvailable() ) {
return GRUB_ERR_NO_TPM;
grub_fatal( "tpm not available" );
}

if ( ! input->IPBLength || ! input->OPBLength ) {
return grub_error (GRUB_ERR_TPM, N_("tcg_passThroughToTPM: ! input->IPBLength || ! input->OPBLength"));
grub_fatal( "tcg_passThroughToTPM: ! input->IPBLength || ! input->OPBLength" );
}

/* copy input buffer */
Expand All @@ -190,10 +189,8 @@ tcg_passThroughToTPM( const PassThroughToTPM_InputParamBlock* input, PassThrough

asm_tcg_passThroughToTPM( &args );

*returnCode = args.out_eax;

if ( *returnCode != TCG_PC_OK ) {
return grub_error( GRUB_ERR_TPM, N_( "tcg_passThroughToTPM: asm_tcg_passThroughToTPM failed: %x" ), *returnCode );
if ( args.out_eax != TCG_PC_OK ) {
grub_fatal( "tcg_passThroughToTPM: asm_tcg_passThroughToTPM failed: %x", args.out_eax );
}

/* copy output_buffer */
Expand All @@ -207,17 +204,16 @@ tcg_passThroughToTPM( const PassThroughToTPM_InputParamBlock* input, PassThrough
output->OPBLength should be the same as input->OPBLength
But they are not ?!
output->Reserved has to be zero. But it is not. */

return GRUB_ERR_NONE;
}

static grub_err_t
/* grub_fatal() on error */
static void
grub_TPM_measure( const grub_uint8_t* inDigest, const unsigned long index ) {

CHECK_FOR_NULL_ARGUMENT( inDigest );

if( ! grub_TPM_isAvailable() ) {
return GRUB_ERR_NO_TPM;
grub_fatal( "tpm not available" );
}

ExtendIncoming* extendInput;
Expand All @@ -231,7 +227,7 @@ grub_TPM_measure( const grub_uint8_t* inDigest, const unsigned long index ) {

passThroughInput = grub_zalloc( inputlen );
if( ! passThroughInput ) {
return grub_error( GRUB_ERR_OUT_OF_MEMORY, N_( "grub_TPM_measure: memory allocation failed" ) );
grub_fatal( "grub_TPM_measure: memory allocation failed" );
}

passThroughInput->IPBLength = inputlen;
Expand All @@ -248,17 +244,10 @@ grub_TPM_measure( const grub_uint8_t* inDigest, const unsigned long index ) {
passThroughOutput = grub_zalloc( outputlen );
if( ! passThroughOutput ) {
grub_free( passThroughInput );
return grub_error( GRUB_ERR_OUT_OF_MEMORY, N_( "grub_TPM_measure: memory allocation failed" ) );
grub_fatal( "grub_TPM_measure: memory allocation failed" );
}

grub_uint32_t passThrough_TPM_ReturnCode;
grub_err_t err = tcg_passThroughToTPM( passThroughInput, passThroughOutput, &passThrough_TPM_ReturnCode );

if( err != GRUB_ERR_NONE ) {
grub_free( passThroughInput );
grub_free( passThroughOutput );
return err;
}
tcg_passThroughToTPM( passThroughInput, passThroughOutput );
grub_free( passThroughInput );

extendOutput = (void *)passThroughOutput->TPMOperandOut;
Expand All @@ -268,9 +257,9 @@ grub_TPM_measure( const grub_uint8_t* inDigest, const unsigned long index ) {
grub_free( passThroughOutput );

if( tpmExtendReturnCode == TPM_BADINDEX ) {
return grub_error( GRUB_ERR_TPM, N_( "grub_TPM_measure: bad pcr index" ) );
grub_fatal( "grub_TPM_measure: bad pcr index" );
}
return grub_error( GRUB_ERR_TPM, N_( "grub_TPM_measure: tpmExtendReturnCode: %x" ), tpmExtendReturnCode );
grub_fatal( "grub_TPM_measure: tpmExtendReturnCode: %x", tpmExtendReturnCode );
}

#ifdef TGRUB_DEBUG
Expand All @@ -280,7 +269,6 @@ grub_TPM_measure( const grub_uint8_t* inDigest, const unsigned long index ) {
#endif

grub_free( passThroughOutput );
return GRUB_ERR_NONE;
}

static unsigned int grubTPM_AvailabilityAlreadyChecked = 0;
Expand Down Expand Up @@ -312,14 +300,14 @@ grub_TPM_isAvailable( void ) {
return grubTPM_isAvailable;
}

/* Returns 0 on error. */
grub_err_t
/* grub_fatal() on error */
void
grub_TPM_measureString( const char* string ) {

CHECK_FOR_NULL_ARGUMENT( string )

if( ! grub_TPM_isAvailable() ) {
return GRUB_ERR_NO_TPM;
grub_fatal( "tpm not available" );
}

/* hash string */
Expand All @@ -328,7 +316,7 @@ grub_TPM_measureString( const char* string ) {
grub_err_t err = sha1_hash_string( string, result );

if( err != GRUB_ERR_NONE ) {
return err;
grub_fatal( "grub_TPM_measureString: sha1_hash_string failed." );
}

/* convert from uint32_t to uint8_t */
Expand All @@ -349,42 +337,38 @@ grub_TPM_measureString( const char* string ) {
#endif

/* measure */
err = grub_TPM_measure( convertedResult, TPM_COMMAND_MEASUREMENT_PCR );

if( err != GRUB_ERR_NONE ) {
return err;
}

return GRUB_ERR_NONE;
grub_TPM_measure( convertedResult, TPM_COMMAND_MEASUREMENT_PCR );
}

grub_err_t
/* grub_fatal() on error */
void
grub_TPM_measureFile( const char* filename, const unsigned long index ) {

CHECK_FOR_NULL_ARGUMENT( filename )

if( ! grub_TPM_isAvailable() ) {
return GRUB_ERR_NO_TPM;
grub_fatal( "tpm not available." );
}

/* open file */
grub_file_t file = grub_file_open( filename );
if( ! file ) {
return grub_errno;
grub_print_error();
grub_fatal( "grub_TPM_measureFile: grub_file_open failed." );
}

/* hash file */
grub_uint32_t result[5];
grub_err_t err = sha1_hash_file( file, result );

if( err != GRUB_ERR_NONE ) {
return err;
grub_fatal( "grub_TPM_measureFile: sha1_hash_file failed." );
}

grub_file_close( file );

if ( grub_errno ) {
return grub_errno;
grub_fatal( "grub_TPM_measureFile: grub_file_close failed." );
}

/* convert from uint32_t to uint8_t */
Expand All @@ -403,30 +387,24 @@ grub_TPM_measureFile( const char* filename, const unsigned long index ) {
#endif

/* measure */
err = grub_TPM_measure( convertedResult, index );

if( err != GRUB_ERR_NONE ) {
return err;
}

return GRUB_ERR_NONE;
grub_TPM_measure( convertedResult, index );
}

grub_err_t
void
grub_TPM_measureBuffer( const void* buffer, const grub_uint32_t bufferLen, const unsigned long index ) {

CHECK_FOR_NULL_ARGUMENT( buffer )

if( ! grub_TPM_isAvailable() ) {
return GRUB_ERR_NO_TPM;
grub_fatal( "tpm not available." );
}

/* hash buffer */
grub_uint32_t result[5];
grub_err_t err = sha1_hash_buffer( buffer, bufferLen, result );

if( err != GRUB_ERR_NONE ) {
return err;
grub_fatal( "grub_TPM_measureBuffer: sha1_hash_buffer failed." );
}

/* convert from uint32_t to uint8_t */
Expand All @@ -445,13 +423,6 @@ grub_TPM_measureBuffer( const void* buffer, const grub_uint32_t bufferLen, const
#endif

/* measure */
err = grub_TPM_measure( convertedResult, index );

if( err != GRUB_ERR_NONE ) {
return err;
}

return GRUB_ERR_NONE;
grub_TPM_measure( convertedResult, index );
}

/* End TCG Extension */
10 changes: 1 addition & 9 deletions grub-core/loader/i386/pc/chainloader.c
Original file line number Diff line number Diff line change
Expand Up @@ -242,16 +242,8 @@ grub_chainloader_cmd (const char *filename, grub_chainloader_flags_t flags)
grub_loader_set (grub_chainloader_boot, grub_chainloader_unload, 1);

/* Begin TCG Extension */
grub_err_t err = grub_TPM_measureFile( (char*)filename, TPM_LOADED_FILES_PCR );
grub_TPM_measureFile( (char*)filename, TPM_LOADED_FILES_PCR );

// TrustedGRUB2 should work without TPM too, so ignore TPM error here
if( err == GRUB_ERR_NO_TPM ) {
err = GRUB_ERR_NONE;
}

if( err != GRUB_ERR_NONE ) {
goto fail;
}
/* End TCG Extension */

return;
Expand Down
12 changes: 1 addition & 11 deletions grub-core/loader/i386/pc/ntldr.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,17 +139,7 @@ grub_cmd_ntldr (grub_command_t cmd __attribute__ ((unused)),
grub_loader_set (grub_ntldr_boot, grub_ntldr_unload, 1);

/* Begin TCG Extension */
err = grub_TPM_measureFile( argv[0], TPM_LOADED_FILES_PCR );

// TrustedGRUB2 should work without TPM too, so ignore TPM error here
if( err == GRUB_ERR_NO_TPM ) {
err = GRUB_ERR_NONE;
}

if( err != GRUB_ERR_NONE ) {
goto fail;
}

grub_TPM_measureFile( argv[0], TPM_LOADED_FILES_PCR );
/* End TCG Extension */

return GRUB_ERR_NONE;
Expand Down
2 changes: 1 addition & 1 deletion grub-core/normal/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
/* BEGIN TCG EXTENSION */
#include <grub/machine/tpm.h>

#define TGRUB_VERSION "1.00"
#define TGRUB_VERSION "1.01"
/* END TCG EXTENSION */


Expand Down
Loading

0 comments on commit d716a19

Please sign in to comment.