diff mbox series

[v2,2/3] tcgbios: Implement tpm_hash_log_extend_event_buffer

Message ID 20200401145755.891080-3-stefanb@linux.vnet.ibm.com
State Superseded
Headers show
Series vTPM: Measure the bootloader | expand

Commit Message

Stefan Berger April 1, 2020, 2:57 p.m. UTC
From: Stefan Berger <stefanb@linux.ibm.com>

Implement tpm_hash_log_extend_event_buffer() that allows to measure
the contents of a buffer into a given PCR and log it with the
given event type and description. The caller may choose to have
the size of an ELF image file detected so that only data from the
ELF image are hashed rather than the much larger buffer.

Besides using this function call now for measuring the bootloader
read from a GPT partition, we also intend to use it for calls from
the firmware API that allow us to measure and log data from a boot
loader, such as grub. Grub will then invoke this function with a
buffer whose size it knows and will not need the ELF file size
detection.

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
---
 lib/libtpm/tcgbios.c | 47 ++++++++++++++++++++++++++++++++++++++++++++
 lib/libtpm/tcgbios.h |  5 +++++
 lib/libtpm/tpm.code  | 19 ++++++++++++++++++
 lib/libtpm/tpm.in    |  1 +
 4 files changed, 72 insertions(+)

Comments

Alexey Kardashevskiy May 8, 2020, 1:11 a.m. UTC | #1
On 02/04/2020 01:57, Stefan Berger wrote:
> From: Stefan Berger <stefanb@linux.ibm.com>
> 
> Implement tpm_hash_log_extend_event_buffer() that allows to measure
> the contents of a buffer into a given PCR and log it with the
> given event type and description. The caller may choose to have
> the size of an ELF image file detected so that only data from the
> ELF image are hashed rather than the much larger buffer.
> 
> Besides using this function call now for measuring the bootloader
> read from a GPT partition, we also intend to use it for calls from
> the firmware API that allow us to measure and log data from a boot
> loader, such as grub. Grub will then invoke this function with a
> buffer whose size it knows and will not need the ELF file size
> detection.
> 
> Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
> ---
>  lib/libtpm/tcgbios.c | 47 ++++++++++++++++++++++++++++++++++++++++++++
>  lib/libtpm/tcgbios.h |  5 +++++
>  lib/libtpm/tpm.code  | 19 ++++++++++++++++++
>  lib/libtpm/tpm.in    |  1 +
>  4 files changed, 72 insertions(+)
> 
> diff --git a/lib/libtpm/tcgbios.c b/lib/libtpm/tcgbios.c
> index be6c3d1..7dcf57c 100644
> --- a/lib/libtpm/tcgbios.c
> +++ b/lib/libtpm/tcgbios.c
> @@ -33,6 +33,7 @@
>  #include "helpers.h"
>  #include "version.h"
>  #include "OF.h"
> +#include "libelf.h"
>  
>  #undef TCGBIOS_DEBUG
>  //#define TCGBIOS_DEBUG
> @@ -852,6 +853,52 @@ static uint32_t tpm_add_measurement_to_log(uint32_t pcrindex,
>  	return tpm_log_event_long(&le.hdr, digest_len, info, infolen);
>  }
>  
> +/*
> + * Measure the contents of a buffer into the given PCR and log it with the
> + * given eventtype. If is_elf is true, try to determine the size of the
> + * ELF file in the buffer and use its size rather than the much larger data
> + * buffer it is held in. In case of failure to detect the ELF file size,
> + * log an error.
> + *
> + * Input parameters:
> + *  @pcrindex : PCR to extend
> + *  @eventtype : type of event
> + *  @data: the buffer to measure
> + *  @datalen: length of the buffer
> + *  @desc: The description to log
> + *  @desclen: The length of the description
> + *  @is_elf: Whether data buffer holds an ELF file and we should determine
> + *           the original file size.
> + *
> + *  Returns 0 on success, an error code otherwise.
> + */
> +uint32_t tpm_hash_log_extend_event_buffer(uint32_t pcrindex, uint32_t eventtype,
> +					  const void *data, uint64_t datalen,
> +					  const char *desc, uint32_t desclen,
> +					  bool is_elf)
> +{
> +	long len;
> +	char buf[256];
> +	int n;
> +
> +	if (is_elf) {
> +		len = elf_get_file_size(data, datalen);
> +		if (len > 0) {
> +			datalen = len;
> +		} else {
> +			n = snprintf(buf, sizeof(buf) - 1,
> +			             "BAD ELF FILE: %s", desc);
> +			buf[n] = 0;


The SLOF's snprintf always writes 0 in the end.



> +			return tpm_add_measurement_to_log(pcrindex, eventtype,
> +					  buf, strlen(buf),
> +					  (uint8_t *)buf, strlen(buf));
> +		}
> +	}
> +	return tpm_add_measurement_to_log(pcrindex, eventtype,
> +					  desc, desclen,
> +					  data, datalen);
> +}
> +
>  /*
>   * Add an EV_ACTION measurement to the list of measurements
>   */
> diff --git a/lib/libtpm/tcgbios.h b/lib/libtpm/tcgbios.h
> index 8174d86..0e7fb8c 100644
> --- a/lib/libtpm/tcgbios.h
> +++ b/lib/libtpm/tcgbios.h
> @@ -32,5 +32,10 @@ void tpm20_menu(void);
>  void tpm_gpt_set_lba1(const uint8_t *addr, uint32_t length);
>  void tpm_gpt_add_entry(const uint8_t *addr, uint32_t length);
>  uint32_t tpm_measure_gpt(void);
> +uint32_t tpm_hash_log_extend_event_buffer(uint32_t pcrindex,
> +					  uint32_t eventtype,
> +					  const void *data, uint64_t datalen,
> +					  const char *desc, uint32_t desclen,
> +					  bool is_elf);
>  
>  #endif /* TCGBIOS_H */
> diff --git a/lib/libtpm/tpm.code b/lib/libtpm/tpm.code
> index 205c608..d67d2c3 100644
> --- a/lib/libtpm/tpm.code
> +++ b/lib/libtpm/tpm.code
> @@ -169,3 +169,22 @@ PRIM(tpm_X2d_measure_X2d_gpt)
>  	PUSH;
>  	TOS.n = tpm_measure_gpt();
>  MIRP
> +

Unrelated.

> +/***********************************************************************************************************/
> +/* Firmware API                                                                                            */
> +/* SLOF:   tpm-hash-log-extend-event-buffer ( pcr evt data-ptr data-len desc-ptr desclen is_elf -- errcode ) */
> +/* LIBTPM: errcode = tpm-hash-log-extend-event-buffer                                                        */
> +/***********************************************************************************************************/
> +PRIM(tpm_X2d_hash_X2d_log_X2d_extend_X2d_event_X2d_buffer)
> +	uint32_t is_elf  = TOS.u; POP;
> +	uint32_t desclen = TOS.u; POP;
> +	const char *desc = TOS.a; POP;
> +	uint64_t datalen = TOS.u; POP;
> +	const void *data = TOS.a; POP;
> +	uint32_t eventtype = TOS.u; POP;
> +	uint32_t pcrindex = TOS.u;
> +
> +	TOS.n = tpm_hash_log_extend_event_buffer(pcrindex, eventtype,
> +					         data, datalen,
> +					         desc, desclen, is_elf);
> +MIRP
> diff --git a/lib/libtpm/tpm.in b/lib/libtpm/tpm.in
> index bdbc47d..fb54754 100644
> --- a/lib/libtpm/tpm.in
> +++ b/lib/libtpm/tpm.in
> @@ -28,3 +28,4 @@ cod(tpm20-menu)
>  cod(tpm-gpt-set-lba1)
>  cod(tpm-gpt-add-entry)
>  cod(tpm-measure-gpt)
> +cod(tpm-hash-log-extend-event-buffer)
>
Stefan Berger May 8, 2020, 9:02 p.m. UTC | #2
On 5/7/20 9:11 PM, Alexey Kardashevskiy wrote:
>
> On 02/04/2020 01:57, Stefan Berger wrote:
>> From: Stefan Berger <stefanb@linux.ibm.com>
>>
>> Implement tpm_hash_log_extend_event_buffer() that allows to measure
>> the contents of a buffer into a given PCR and log it with the
>> given event type and description. The caller may choose to have
>> the size of an ELF image file detected so that only data from the
>> ELF image are hashed rather than the much larger buffer.
>>
>> Besides using this function call now for measuring the bootloader
>> read from a GPT partition, we also intend to use it for calls from
>> the firmware API that allow us to measure and log data from a boot
>> loader, such as grub. Grub will then invoke this function with a
>> buffer whose size it knows and will not need the ELF file size
>> detection.
>>
>> Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
>> ---
>>   lib/libtpm/tcgbios.c | 47 ++++++++++++++++++++++++++++++++++++++++++++
>>   lib/libtpm/tcgbios.h |  5 +++++
>>   lib/libtpm/tpm.code  | 19 ++++++++++++++++++
>>   lib/libtpm/tpm.in    |  1 +
>>   4 files changed, 72 insertions(+)
>>
>> diff --git a/lib/libtpm/tcgbios.c b/lib/libtpm/tcgbios.c
>> index be6c3d1..7dcf57c 100644
>> --- a/lib/libtpm/tcgbios.c
>> +++ b/lib/libtpm/tcgbios.c
>> @@ -33,6 +33,7 @@
>>   #include "helpers.h"
>>   #include "version.h"
>>   #include "OF.h"
>> +#include "libelf.h"
>>   
>>   #undef TCGBIOS_DEBUG
>>   //#define TCGBIOS_DEBUG
>> @@ -852,6 +853,52 @@ static uint32_t tpm_add_measurement_to_log(uint32_t pcrindex,
>>   	return tpm_log_event_long(&le.hdr, digest_len, info, infolen);
>>   }
>>   
>> +/*
>> + * Measure the contents of a buffer into the given PCR and log it with the
>> + * given eventtype. If is_elf is true, try to determine the size of the
>> + * ELF file in the buffer and use its size rather than the much larger data
>> + * buffer it is held in. In case of failure to detect the ELF file size,
>> + * log an error.
>> + *
>> + * Input parameters:
>> + *  @pcrindex : PCR to extend
>> + *  @eventtype : type of event
>> + *  @data: the buffer to measure
>> + *  @datalen: length of the buffer
>> + *  @desc: The description to log
>> + *  @desclen: The length of the description
>> + *  @is_elf: Whether data buffer holds an ELF file and we should determine
>> + *           the original file size.
>> + *
>> + *  Returns 0 on success, an error code otherwise.
>> + */
>> +uint32_t tpm_hash_log_extend_event_buffer(uint32_t pcrindex, uint32_t eventtype,
>> +					  const void *data, uint64_t datalen,
>> +					  const char *desc, uint32_t desclen,
>> +					  bool is_elf)
>> +{
>> +	long len;
>> +	char buf[256];
>> +	int n;
>> +
>> +	if (is_elf) {
>> +		len = elf_get_file_size(data, datalen);
>> +		if (len > 0) {
>> +			datalen = len;
>> +		} else {
>> +			n = snprintf(buf, sizeof(buf) - 1,
>> +			             "BAD ELF FILE: %s", desc);
>> +			buf[n] = 0;
>
> The SLOF's snprintf always writes 0 in the end.

Will fix.


>
>
>
>> +			return tpm_add_measurement_to_log(pcrindex, eventtype,
>> +					  buf, strlen(buf),
>> +					  (uint8_t *)buf, strlen(buf));
>> +		}
>> +	}
>> +	return tpm_add_measurement_to_log(pcrindex, eventtype,
>> +					  desc, desclen,
>> +					  data, datalen);
>> +}
>> +
>>   /*
>>    * Add an EV_ACTION measurement to the list of measurements
>>    */
>> diff --git a/lib/libtpm/tcgbios.h b/lib/libtpm/tcgbios.h
>> index 8174d86..0e7fb8c 100644
>> --- a/lib/libtpm/tcgbios.h
>> +++ b/lib/libtpm/tcgbios.h
>> @@ -32,5 +32,10 @@ void tpm20_menu(void);
>>   void tpm_gpt_set_lba1(const uint8_t *addr, uint32_t length);
>>   void tpm_gpt_add_entry(const uint8_t *addr, uint32_t length);
>>   uint32_t tpm_measure_gpt(void);
>> +uint32_t tpm_hash_log_extend_event_buffer(uint32_t pcrindex,
>> +					  uint32_t eventtype,
>> +					  const void *data, uint64_t datalen,
>> +					  const char *desc, uint32_t desclen,
>> +					  bool is_elf);
>>   
>>   #endif /* TCGBIOS_H */
>> diff --git a/lib/libtpm/tpm.code b/lib/libtpm/tpm.code
>> index 205c608..d67d2c3 100644
>> --- a/lib/libtpm/tpm.code
>> +++ b/lib/libtpm/tpm.code
>> @@ -169,3 +169,22 @@ PRIM(tpm_X2d_measure_X2d_gpt)
>>   	PUSH;
>>   	TOS.n = tpm_measure_gpt();
>>   MIRP
>> +
> Unrelated.
>
>> +/***********************************************************************************************************/
>> +/* Firmware API                                                                                            */
>> +/* SLOF:   tpm-hash-log-extend-event-buffer ( pcr evt data-ptr data-len desc-ptr desclen is_elf -- errcode ) */
>> +/* LIBTPM: errcode = tpm-hash-log-extend-event-buffer                                                        */
>> +/***********************************************************************************************************/
>> +PRIM(tpm_X2d_hash_X2d_log_X2d_extend_X2d_event_X2d_buffer)
>> +	uint32_t is_elf  = TOS.u; POP;
>> +	uint32_t desclen = TOS.u; POP;
>> +	const char *desc = TOS.a; POP;
>> +	uint64_t datalen = TOS.u; POP;
>> +	const void *data = TOS.a; POP;
>> +	uint32_t eventtype = TOS.u; POP;
>> +	uint32_t pcrindex = TOS.u;
>> +
>> +	TOS.n = tpm_hash_log_extend_event_buffer(pcrindex, eventtype,
>> +					         data, datalen,
>> +					         desc, desclen, is_elf);
>> +MIRP
>> diff --git a/lib/libtpm/tpm.in b/lib/libtpm/tpm.in
>> index bdbc47d..fb54754 100644
>> --- a/lib/libtpm/tpm.in
>> +++ b/lib/libtpm/tpm.in
>> @@ -28,3 +28,4 @@ cod(tpm20-menu)
>>   cod(tpm-gpt-set-lba1)
>>   cod(tpm-gpt-add-entry)
>>   cod(tpm-measure-gpt)
>> +cod(tpm-hash-log-extend-event-buffer)
>>
Stefan Berger May 8, 2020, 9:16 p.m. UTC | #3
On 5/7/20 9:11 PM, Alexey Kardashevskiy wrote:
>
> On 02/04/2020 01:57, Stefan Berger wrote:
>
>>   #endif /* TCGBIOS_H */
>> diff --git a/lib/libtpm/tpm.code b/lib/libtpm/tpm.code
>> index 205c608..d67d2c3 100644
>> --- a/lib/libtpm/tpm.code
>> +++ b/lib/libtpm/tpm.code
>> @@ -169,3 +169,22 @@ PRIM(tpm_X2d_measure_X2d_gpt)
>>   	PUSH;
>>   	TOS.n = tpm_measure_gpt();
>>   MIRP
>> +
> Unrelated.


What do you mean ?


>
>> +/***********************************************************************************************************/
>> +/* Firmware API                                                                                            */
>> +/* SLOF:   tpm-hash-log-extend-event-buffer ( pcr evt data-ptr data-len desc-ptr desclen is_elf -- errcode ) */
>> +/* LIBTPM: errcode = tpm-hash-log-extend-event-buffer                                                        */
>> +/***********************************************************************************************************/
>> +PRIM(tpm_X2d_hash_X2d_log_X2d_extend_X2d_event_X2d_buffer)
>> +	uint32_t is_elf  = TOS.u; POP;
>> +	uint32_t desclen = TOS.u; POP;
>> +	const char *desc = TOS.a; POP;
>> +	uint64_t datalen = TOS.u; POP;
>> +	const void *data = TOS.a; POP;
>> +	uint32_t eventtype = TOS.u; POP;
>> +	uint32_t pcrindex = TOS.u;
>> +
>> +	TOS.n = tpm_hash_log_extend_event_buffer(pcrindex, eventtype,
>> +					         data, datalen,
>> +					         desc, desclen, is_elf);
>> +MIRP
>> diff --git a/lib/libtpm/tpm.in b/lib/libtpm/tpm.in
>> index bdbc47d..fb54754 100644
>> --- a/lib/libtpm/tpm.in
>> +++ b/lib/libtpm/tpm.in
>> @@ -28,3 +28,4 @@ cod(tpm20-menu)
>>   cod(tpm-gpt-set-lba1)
>>   cod(tpm-gpt-add-entry)
>>   cod(tpm-measure-gpt)
>> +cod(tpm-hash-log-extend-event-buffer)
>>
Alexey Kardashevskiy May 9, 2020, 2:34 a.m. UTC | #4
On 09/05/2020 07:16, Stefan Berger wrote:
> On 5/7/20 9:11 PM, Alexey Kardashevskiy wrote:
>>
>> On 02/04/2020 01:57, Stefan Berger wrote:
>>
>>>   #endif /* TCGBIOS_H */
>>> diff --git a/lib/libtpm/tpm.code b/lib/libtpm/tpm.code
>>> index 205c608..d67d2c3 100644
>>> --- a/lib/libtpm/tpm.code
>>> +++ b/lib/libtpm/tpm.code
>>> @@ -169,3 +169,22 @@ PRIM(tpm_X2d_measure_X2d_gpt)
>>>       PUSH;
>>>       TOS.n = tpm_measure_gpt();
>>>   MIRP
>>> +
>> Unrelated.
> 
> 
> What do you mean ?


Ignore it, I thought I saw a new isolated empty line when was replying
to the patch, got confused with quotations and wraps.

> 
> 
>>
>>> +/***********************************************************************************************************/
>>>
>>> +/* Firmware
>>> API                                                                                           
>>> */
>>> +/* SLOF:   tpm-hash-log-extend-event-buffer ( pcr evt data-ptr
>>> data-len desc-ptr desclen is_elf -- errcode ) */
>>> +/* LIBTPM: errcode =
>>> tpm-hash-log-extend-event-buffer                                                       
>>> */
>>> +/***********************************************************************************************************/
>>>
>>> +PRIM(tpm_X2d_hash_X2d_log_X2d_extend_X2d_event_X2d_buffer)
>>> +    uint32_t is_elf  = TOS.u; POP;
>>> +    uint32_t desclen = TOS.u; POP;
>>> +    const char *desc = TOS.a; POP;
>>> +    uint64_t datalen = TOS.u; POP;
>>> +    const void *data = TOS.a; POP;
>>> +    uint32_t eventtype = TOS.u; POP;
>>> +    uint32_t pcrindex = TOS.u;
>>> +
>>> +    TOS.n = tpm_hash_log_extend_event_buffer(pcrindex, eventtype,
>>> +                             data, datalen,
>>> +                             desc, desclen, is_elf);
>>> +MIRP
>>> diff --git a/lib/libtpm/tpm.in b/lib/libtpm/tpm.in
>>> index bdbc47d..fb54754 100644
>>> --- a/lib/libtpm/tpm.in
>>> +++ b/lib/libtpm/tpm.in
>>> @@ -28,3 +28,4 @@ cod(tpm20-menu)
>>>   cod(tpm-gpt-set-lba1)
>>>   cod(tpm-gpt-add-entry)
>>>   cod(tpm-measure-gpt)
>>> +cod(tpm-hash-log-extend-event-buffer)
>>>
>
diff mbox series

Patch

diff --git a/lib/libtpm/tcgbios.c b/lib/libtpm/tcgbios.c
index be6c3d1..7dcf57c 100644
--- a/lib/libtpm/tcgbios.c
+++ b/lib/libtpm/tcgbios.c
@@ -33,6 +33,7 @@ 
 #include "helpers.h"
 #include "version.h"
 #include "OF.h"
+#include "libelf.h"
 
 #undef TCGBIOS_DEBUG
 //#define TCGBIOS_DEBUG
@@ -852,6 +853,52 @@  static uint32_t tpm_add_measurement_to_log(uint32_t pcrindex,
 	return tpm_log_event_long(&le.hdr, digest_len, info, infolen);
 }
 
+/*
+ * Measure the contents of a buffer into the given PCR and log it with the
+ * given eventtype. If is_elf is true, try to determine the size of the
+ * ELF file in the buffer and use its size rather than the much larger data
+ * buffer it is held in. In case of failure to detect the ELF file size,
+ * log an error.
+ *
+ * Input parameters:
+ *  @pcrindex : PCR to extend
+ *  @eventtype : type of event
+ *  @data: the buffer to measure
+ *  @datalen: length of the buffer
+ *  @desc: The description to log
+ *  @desclen: The length of the description
+ *  @is_elf: Whether data buffer holds an ELF file and we should determine
+ *           the original file size.
+ *
+ *  Returns 0 on success, an error code otherwise.
+ */
+uint32_t tpm_hash_log_extend_event_buffer(uint32_t pcrindex, uint32_t eventtype,
+					  const void *data, uint64_t datalen,
+					  const char *desc, uint32_t desclen,
+					  bool is_elf)
+{
+	long len;
+	char buf[256];
+	int n;
+
+	if (is_elf) {
+		len = elf_get_file_size(data, datalen);
+		if (len > 0) {
+			datalen = len;
+		} else {
+			n = snprintf(buf, sizeof(buf) - 1,
+			             "BAD ELF FILE: %s", desc);
+			buf[n] = 0;
+			return tpm_add_measurement_to_log(pcrindex, eventtype,
+					  buf, strlen(buf),
+					  (uint8_t *)buf, strlen(buf));
+		}
+	}
+	return tpm_add_measurement_to_log(pcrindex, eventtype,
+					  desc, desclen,
+					  data, datalen);
+}
+
 /*
  * Add an EV_ACTION measurement to the list of measurements
  */
diff --git a/lib/libtpm/tcgbios.h b/lib/libtpm/tcgbios.h
index 8174d86..0e7fb8c 100644
--- a/lib/libtpm/tcgbios.h
+++ b/lib/libtpm/tcgbios.h
@@ -32,5 +32,10 @@  void tpm20_menu(void);
 void tpm_gpt_set_lba1(const uint8_t *addr, uint32_t length);
 void tpm_gpt_add_entry(const uint8_t *addr, uint32_t length);
 uint32_t tpm_measure_gpt(void);
+uint32_t tpm_hash_log_extend_event_buffer(uint32_t pcrindex,
+					  uint32_t eventtype,
+					  const void *data, uint64_t datalen,
+					  const char *desc, uint32_t desclen,
+					  bool is_elf);
 
 #endif /* TCGBIOS_H */
diff --git a/lib/libtpm/tpm.code b/lib/libtpm/tpm.code
index 205c608..d67d2c3 100644
--- a/lib/libtpm/tpm.code
+++ b/lib/libtpm/tpm.code
@@ -169,3 +169,22 @@  PRIM(tpm_X2d_measure_X2d_gpt)
 	PUSH;
 	TOS.n = tpm_measure_gpt();
 MIRP
+
+/***********************************************************************************************************/
+/* Firmware API                                                                                            */
+/* SLOF:   tpm-hash-log-extend-event-buffer ( pcr evt data-ptr data-len desc-ptr desclen is_elf -- errcode ) */
+/* LIBTPM: errcode = tpm-hash-log-extend-event-buffer                                                        */
+/***********************************************************************************************************/
+PRIM(tpm_X2d_hash_X2d_log_X2d_extend_X2d_event_X2d_buffer)
+	uint32_t is_elf  = TOS.u; POP;
+	uint32_t desclen = TOS.u; POP;
+	const char *desc = TOS.a; POP;
+	uint64_t datalen = TOS.u; POP;
+	const void *data = TOS.a; POP;
+	uint32_t eventtype = TOS.u; POP;
+	uint32_t pcrindex = TOS.u;
+
+	TOS.n = tpm_hash_log_extend_event_buffer(pcrindex, eventtype,
+					         data, datalen,
+					         desc, desclen, is_elf);
+MIRP
diff --git a/lib/libtpm/tpm.in b/lib/libtpm/tpm.in
index bdbc47d..fb54754 100644
--- a/lib/libtpm/tpm.in
+++ b/lib/libtpm/tpm.in
@@ -28,3 +28,4 @@  cod(tpm20-menu)
 cod(tpm-gpt-set-lba1)
 cod(tpm-gpt-add-entry)
 cod(tpm-measure-gpt)
+cod(tpm-hash-log-extend-event-buffer)