Introduce SPI TPM v2.0 support
cover Introduce SPI TPM v2.0 support
Current U-Boot supports TPM v1.2 specification. The new specification (v2.0) is not backward compatible and renames/introduces several functions.
This series introduces a new SPI driver following the TPM v2.0 specification. It has been tested on a ST TPM but should be usable with others v2.0 compliant chips.
Then, basic functionalities are introduced one by one for the v2.0 specification. The INIT command now can receive a parameter to distinguish further TPMv1/TPMv2 commands. After that, the library itself will know which one is pertinent and will return a special error if the desired command is not supported for the selected specification.
Available commands for v2.0 TPMs are:
* STARTUP
* SELF TEST
* CLEAR
* PCR EXTEND
* PCR READ
* GET CAPABILITY
* DICTIONARY ATTACK LOCK RESET
* DICTIONARY ATTACK CHANGE PARAMETERS
* HIERARCHY CHANGE AUTH
Two commands have been written but could not be tested (unsupported by the TPM chosen):
* PCR CHANGE AUTH POLICY
* PCR CHANGE AUTH VALUE
With this set of function, minimal TPMv2.0 handling is possible with the following sequence.
* First, initialize the TPM stack in U-Boot: "TPM2" is a new parameter to discern the format of the commands:
Quoted 1 line
tpm init TPM2
* Then send the STARTUP command to the TPM. The flag is slightly different between the revisions.
Quoted 1 line
tpm startup
TPM2_SU_CLEAR
* To enable full TPM capabilities, continue the tests (or do them all again). It seems like self_test_full always waits for the operation to finish, while continue_self_test returns a busy state if called to early.
Quoted 2 lines
tpm
continue_self_test
tpmself_test_full
* Manage passwords (force_clear also resets a lot of internal stuff). Olderly, TAKE OWNERSHIP == CLEAR + CHANGE AUTH. LOCKOUT is an example, ENDORSEMENT and PLATFORM hierarchies are available too:
Quoted 2 lines
tpm
force_clearTPM2_RH_LOCKOUT[<pw>]
tpmchange_authTPM2_RH_LOCKOUT<new_pw> [<old_pw>]
* Dictionary Attack Mitigation (DAM) parameters can be changed. It is possible to reset the failure counter and disable the lockout (values erased after a CLEAR). It is then possible to check the parameters have been correctly applied.
Quoted 3 lines
tpm
dam_reset_counter[<pw>]
tpmdam_set_parameters0xffff1 0 [<pw>]
tpmget_capability0x00060x020e0x40000004
* PCR policy may be changed (untested).
PCR can be extended (no protection against packet replay yet). PCR can be read (the counter with the number of "extensions" is also given).
Quoted 3 lines
tpm
pcr_setauthpolicy0 12345678901234567890123456789012 [<pw>] tpmpcr_read00x4000000
tpmpcr_extend00x4000000
Miquel Raynal (18):
tpm: add Revision ID field in the chip structure
tpm: rename tpm_tis_infineon in tpm_tis_infineon_i2c
tpm: add support for TPMv2 SPI modules
tpm: fix indentation in command list before adding more
tpm: prepare support for TPMv2 commands
tpm: add macros for TPMv2 commands
tpm: add possible traces to analyze buffers returned by the TPM
tpm: handle different buffer sizes
tpm: add TPM2_Startup command support
tpm: add TPM2_SelfTest command support
tpm: add TPM2_Clear command support
tpm: rename the _extend() function to be _pcr_event()
tpm: add TPM2_PCR_Extend command support
tpm: add TPM2_PCR_Read command support
tpm: add TPM2_GetCapability command support
tpm: add dictionary attack mitigation commands support
tpm: add TPM2_HierarchyChangeAuth command support
tpm: add PCR authentication commands support
cmd/tpm.c | 360 +++++++++--
cmd/tpm_test.c | 10 +-
drivers/tpm/Kconfig | 13 +-
drivers/tpm/Makefile | 3 +-
drivers/tpm/tpm_tis.h | 4 +
.../{tpm_tis_infineon.c => tpm_tis_infineon_i2c.c} | 2 +-
drivers/tpm/tpm_tis_spi.c | 656 +++++++++++++++++++++
include/tpm.h | 183 +++++-
lib/tpm.c | 654 ++++++++++++++++++--
9 files changed, 1739 insertions(+), 146 deletions(-)
rename drivers/tpm/{tpm_tis_infineon.c => tpm_tis_infineon_i2c.c} (99%)
create mode 100644 drivers/tpm/tpm_tis_spi.cSignature · 1 line
2.14.1
PATCH 1/18 tpm: add Revision ID field in the chip structure
TPM are shipped with a few read-only register from which we can retrieve for instance:
- vendor ID
- product ID
- revision ID
Product and vendor ID share the same register and are already referenced in the tpm_chip structure. Add the revision ID entry which is missing.
--- drivers/tpm/tpm_tis.h | 1 + 1 file changed, 1 insertion(+)
drivers/tpm/tpm_tis.h +1 -0
@@ -41,6 +41,7 @@ struct tpm_chip {int is_open;int locality;u32 vend_dev; +u8 rid;unsigned long timeout_a, timeout_b, timeout_c, timeout_d;/* msec */ ulong chip_type; };
Signature · 1 line
2.14.1
PATCH 2/18 tpm: rename tpm_tis_infineon in tpm_tis_infineon_i2c
In reply to Miquel RaynalAs the chips driven by tpm_tis_infineon.c are only I2C chips, rename the driver with the _i2c suffix to prepare the venue of its _spi cousin.
Also change the driver name in the U_BOOT_DRIVER structure.
---
drivers/tpm/Kconfig | 4 ++--
drivers/tpm/Makefile | 2 +-
drivers/tpm/{tpm_tis_infineon.c => tpm_tis_infineon_i2c.c} | 2 +-
3 files changed, 4 insertions(+), 4 deletions(-)
rename drivers/tpm/{tpm_tis_infineon.c => tpm_tis_infineon_i2c.c} (99%)drivers/tpm/Kconfig +2 -2
@@ -22,7 +22,7 @@ config TPM_ATMEL_TWI to the device using the standard TPM Interface Specification (TIS) protocol -config TPM_TIS_INFINEON +config TPM_TIS_INFINEON_I2C bool "Enable support for Infineon SLB9635/45 TPMs on I2C" depends on TPM && DM_I2C help
@@ -33,7 +33,7 @@ config TPM_TIS_INFINEON config TPM_TIS_I2C_BURST_LIMITATION bool "Enable I2C burst length limitation" - depends on TPM_TIS_INFINEON + depends on TPM_TIS_INFINEON_I2C help Some broken TPMs have a limitation on the number of bytes they can receive in one message. Enable this option to allow you to set this
drivers/tpm/Makefile +1 -1
@@ -6,7 +6,7 @@ obj-$(CONFIG_TPM) += tpm-uclass.o obj-$(CONFIG_TPM_ATMEL_TWI) += tpm_atmel_twi.o -obj-$(CONFIG_TPM_TIS_INFINEON) += tpm_tis_infineon.o +obj-$(CONFIG_TPM_TIS_INFINEON_I2C) += tpm_tis_infineon_i2c.o obj-$(CONFIG_TPM_TIS_LPC) += tpm_tis_lpc.o obj-$(CONFIG_TPM_TIS_SANDBOX) += tpm_tis_sandbox.o obj-$(CONFIG_TPM_ST33ZP24_I2C) += tpm_tis_st33zp24_i2c.o
drivers/tpm/tpm_tis_infineon_i2c.c renamed from drivers/tpm/tpm_tis_infineon.c +1 -1
@@ -629,7 +629,7 @@ static const struct udevice_id tpm_tis_i2c_ids[] = { };U_BOOT_DRIVER (tpm_tis_i2c) = { - .name ="tpm_tis_infineon" , + .name ="tpm_tis_infineon_i2c" , .id =UCLASS_TPM , .of_match = tpm_tis_i2c_ids, .ops = &tpm_tis_i2c_ops,
Signature · 1 line
2.14.1
PATCH 3/18 tpm: add support for TPMv2 SPI modules
In reply to Miquel RaynalAdd the tpm_tis_spi driver that should support any TPMv2 compliant (SPI) module.
--- drivers/tpm/Kconfig | 9 + drivers/tpm/Makefile | 1 + drivers/tpm/tpm_tis.h | 3 + drivers/tpm/tpm_tis_spi.c | 656 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 669 insertions(+) create mode 100644 drivers/tpm/tpm_tis_spi.c
drivers/tpm/Kconfig +9 -0
@@ -46,6 +46,15 @@ config TPM_TIS_I2C_BURST_LIMITATION_LEN help Use this to set the burst limitation length +config TPM_TIS_SPI + bool "Enable support for TPMv2 SPI chips" + depends on TPM && DM_SPI + help + This driver supports TPMv2 devices connected on the SPI bus. + The usual TPM operations and the 'tpm' command can be used to talk + to the device using the standard TPM Interface Specification (TIS) + protocol + config TPM_TIS_LPC bool "Enable support for Infineon SLB9635/45 TPMs on LPC" depends on TPM && X86
drivers/tpm/Makefile +1 -0
@@ -7,6 +7,7 @@ obj-$(CONFIG_TPM) += tpm-uclass.o obj-$(CONFIG_TPM_ATMEL_TWI) += tpm_atmel_twi.o obj-$(CONFIG_TPM_TIS_INFINEON_I2C) += tpm_tis_infineon_i2c.o +obj-$(CONFIG_TPM_TIS_SPI) += tpm_tis_spi.o obj-$(CONFIG_TPM_TIS_LPC) += tpm_tis_lpc.o obj-$(CONFIG_TPM_TIS_SANDBOX) += tpm_tis_sandbox.o obj-$(CONFIG_TPM_ST33ZP24_I2C) += tpm_tis_st33zp24_i2c.o
drivers/tpm/tpm_tis.h +3 -0
@@ -37,6 +37,9 @@ enum tpm_timeout {#define TPM_RSP_SIZE_BYTE 2#define TPM_RSP_RC_BYTE 6 +/* Number of xfer retries */ +#define TPM_XFER_RETRY 10 +struct tpm_chip {int is_open;int locality;
drivers/tpm/tpm_tis_spi.c new file +656 -0
656 lines not on this page · raw message
Signature · 1 line
2.14.1
PATCH 4/18 tpm: fix indentation in command list before adding more
In reply to Miquel RaynalPrepare the addition of more commands by first indenting correctly the current list.
--- cmd/tpm.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-)
cmd/tpm.c +20 -20
@@ -820,45 +820,45 @@ static int do_tpm_list(cmd_tbl_t *cmdtp, int flag, int argc,static cmd_tbl_t tpm_commands[] = {U_BOOT_CMD_MKENT (info,0 ,1 , do_tpm_info,"" ,"" ),U_BOOT_CMD_MKENT (init,0 ,1 , - do_tpm_init,"" ,"" ), + do_tpm_init,"" ,"" ),U_BOOT_CMD_MKENT (startup,0 ,1 , - do_tpm_startup,"" ,"" ), + do_tpm_startup,"" ,"" ),U_BOOT_CMD_MKENT (self_test_full,0 ,1 , - do_tpm_self_test_full,"" ,"" ), + do_tpm_self_test_full,"" ,"" ),U_BOOT_CMD_MKENT (continue_self_test,0 ,1 , - do_tpm_continue_self_test,"" ,"" ), + do_tpm_continue_self_test,"" ,"" ),U_BOOT_CMD_MKENT (force_clear,0 ,1 , - do_tpm_force_clear,"" ,"" ), + do_tpm_force_clear,"" ,"" ),U_BOOT_CMD_MKENT (physical_enable,0 ,1 , - do_tpm_physical_enable,"" ,"" ), + do_tpm_physical_enable,"" ,"" ),U_BOOT_CMD_MKENT (physical_disable,0 ,1 , - do_tpm_physical_disable,"" ,"" ), + do_tpm_physical_disable,"" ,"" ),U_BOOT_CMD_MKENT (nv_define_space,0 ,1 , - do_tpm_nv_define_space,"" ,"" ), + do_tpm_nv_define_space,"" ,"" ),U_BOOT_CMD_MKENT (nv_read_value,0 ,1 , - do_tpm_nv_read_value,"" ,"" ), + do_tpm_nv_read_value,"" ,"" ),U_BOOT_CMD_MKENT (nv_write_value,0 ,1 , - do_tpm_nv_write_value,"" ,"" ), + do_tpm_nv_write_value,"" ,"" ),U_BOOT_CMD_MKENT (extend,0 ,1 , - do_tpm_extend,"" ,"" ), + do_tpm_extend,"" ,"" ),U_BOOT_CMD_MKENT (pcr_read,0 ,1 , - do_tpm_pcr_read,"" ,"" ), + do_tpm_pcr_read,"" ,"" ),U_BOOT_CMD_MKENT (tsc_physical_presence,0 ,1 , - do_tpm_tsc_physical_presence,"" ,"" ), + do_tpm_tsc_physical_presence,"" ,"" ),U_BOOT_CMD_MKENT (read_pubek,0 ,1 , - do_tpm_read_pubek,"" ,"" ), + do_tpm_read_pubek,"" ,"" ),U_BOOT_CMD_MKENT (physical_set_deactivated,0 ,1 , - do_tpm_physical_set_deactivated,"" ,"" ), + do_tpm_physical_set_deactivated,"" ,"" ),U_BOOT_CMD_MKENT (get_capability,0 ,1 , - do_tpm_get_capability,"" ,"" ), + do_tpm_get_capability,"" ,"" ),U_BOOT_CMD_MKENT (raw_transfer,0 ,1 , - do_tpm_raw_transfer,"" ,"" ), + do_tpm_raw_transfer,"" ,"" ),U_BOOT_CMD_MKENT (nv_define,0 ,1 , - do_tpm_nv_define,"" ,"" ), + do_tpm_nv_define,"" ,"" ),U_BOOT_CMD_MKENT (nv_read,0 ,1 , - do_tpm_nv_read,"" ,"" ), + do_tpm_nv_read,"" ,"" ),U_BOOT_CMD_MKENT (nv_write,0 ,1 , - do_tpm_nv_write,"" ,"" ), + do_tpm_nv_write,"" ,"" ), #ifdef CONFIG_TPM_AUTH_SESSIONSU_BOOT_CMD_MKENT (oiap,0 ,1 , do_tpm_oiap, "", ""),
Signature · 1 line
2.14.1
PATCH 5/18 tpm: prepare support for TPMv2 commands
In reply to Miquel RaynalLater choice between v1 and v2 compliant functions will be handled by a global value in lib/tpm.c that will be accessible through set/get accessors from lib/cmd.c.
This global value is set during the initialization phase if the TPM2 handle is given to the init command.
--- cmd/tpm.c | 37 +++++++++++++++++++++----- include/tpm.h | 20 ++++++++++++++ lib/tpm.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 131 insertions(+), 9 deletions(-)
cmd/tpm.c +30 -7
@@ -89,12 +89,16 @@ static void *parse_byte_string(char *bytes, uint8_t *data, size_t *count_ptr)*/ static int report_return_code (int return_code) { -if (return_code) { -printf ("Error: %d\n" , return_code); -return CMD_RET_FAILURE ; - }else { +if (!return_code)return CMD_RET_SUCCESS ; - } + +if (return_code == -EOPNOTSUPP ) +printf ("TPMv%d error: unavailable command with this spec\n" , +tpm_get_specification ()); +else +printf ("TPM error: %d\n" , return_code); + +return CMD_RET_FAILURE ; }/**
@@ -427,6 +431,24 @@ static int do_tpm_get_capability(cmd_tbl_t *cmdtp, int flag,return report_return_code (rc); } +static int do_tpm_init (cmd_tbl_t *cmdtp,int flag, +int argc,char *const argv[]) +{ +if (argc >2 ) +return CMD_RET_USAGE ; + +if (argc ==2 ) { +if (!strcasecmp ("TPM1" , argv[1 ])) +tpm_set_specification (1 ); +else if (!strcasecmp ("TPM2" , argv[1 ])) +tpm_set_specification (2 ); +else +return CMD_RET_USAGE ; + } + +return report_return_code (tpm_init ()); +} +#define TPM_COMMAND_NO_ARG (cmd) \ static int do_##cmd(cmd_tbl_t *cmdtp, int flag, \ int argc, char * const argv[]) \
@@ -436,7 +458,6 @@ static int do_##cmd(cmd_tbl_t *cmdtp, int flag, \return report_return_code (cmd ()); \ } -TPM_COMMAND_NO_ARG(tpm_init) TPM_COMMAND_NO_ARG(tpm_self_test_full) TPM_COMMAND_NO_ARG(tpm_continue_self_test) TPM_COMMAND_NO_ARG(tpm_force_clear)
@@ -902,8 +923,10 @@ U_BOOT_CMD(tpm, CONFIG_SYS_MAXARGS, 1, do_tpm," - Issue TPM command <cmd> with arguments <args...>.\n" "Admin Startup and State Commands:\n" " info - Show information about the TPM\n" -" init\n" +" init [<type>]\n" " - Put TPM into a state where it waits for 'startup' command.\n" +" <type> is one of TPM1 (default) or TPM2. This choice impacts the way\n" +" other functions will behave.\n" " startup mode\n" " - Issue TPM_Starup command. <mode> is one of TPM_ST_CLEAR,\n" " TPM_ST_STATE, and TPM_ST_DEACTIVATED.\n"
include/tpm.h +20 -0
@@ -30,6 +30,11 @@ enum tpm_startup_type { TPM_ST_DEACTIVATED = 0x0003, }; +enum tpm2_startup_types { +TPM2_SU_CLEAR =0x0000 , +TPM2_SU_STATE =0x0001 , +}; +enum tpm_physical_presence {TPM_PHYSICAL_PRESENCE_HW_DISABLE =0x0200 ,TPM_PHYSICAL_PRESENCE_CMD_DISABLE =0x0100 ,
@@ -417,6 +422,21 @@ int tpm_xfer(struct udevice *dev, const uint8_t *sendbuf, size_t send_size,*/ int tpm_init (void ); +/** +* Assign a value to the global is_nfcv2 boolean to discriminate in the lib +* between the available specifications. +* +* @version: 1 or 2, depending on the supported specification +*/ +int tpm_set_specification (int version); + +/** +* Return the current value of the specification. +* +* @return: 1 or 2, depending on the supported specification +*/ +int tpm_get_specification (void ); +/** * Issue a TPM_Startup command. *
lib/tpm.c +81 -2
211 lines not on this page · raw message
Signature · 1 line
2.14.1
PATCH 6/18 tpm: add macros for TPMv2 commands
In reply to Miquel RaynalTPM commands are much easier to handle with these macros that will transform words or integers into byte string. This way, there is no need to call pack_byte_string() while all variable length in a command are known (and at must 4 bytes, which is a lot of them).
--- lib/tpm.c | 6 ++++++ 1 file changed, 6 insertions(+)
lib/tpm.c +6 -0
@@ -15,6 +15,12 @@/* Internal error of TPM command library */ #define TPM_LIB_ERROR ((uint32_t)~0u) +/* To make strings of commands more easily */ +#define __MSB (x) ((x) >> 8) +#define __LSB (x) ((x) & 0xFF) +#define STRINGIFY16 (x) __MSB(x), __LSB(x) +#define STRINGIFY32 (x) STRINGIFY16((x) >> 16), STRINGIFY16((x) & 0xFFFF) +/* Global boolean to discriminate TPMv2.x from TPMv1.x functions */ static bool is_tpmv2;
Signature · 1 line
2.14.1
PATCH 7/18 tpm: add possible traces to analyze buffers returned by the TPM
In reply to Miquel RaynalWhen debugging, it is welcome to get more information about what the TPM returns. Add the possibility to print the packets received to show their exact content.
--- lib/tpm.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-)
lib/tpm.c +11 -1
@@ -249,6 +249,7 @@ static uint32_t tpm_sendrecv_command(const void *command,int err, ret;uint8_t response_buffer[COMMAND_BUFFER_SIZE ];size_t response_length; +int i;if (response) { response_length = *size_ptr;
@@ -260,15 +261,24 @@ static uint32_t tpm_sendrecv_command(const void *command, ret =uclass_first_device_err (UCLASS_TPM , &dev);if (ret)return ret; + err =tpm_xfer (dev, command,tpm_command_size (command), response, &response_length);if (err <0 )return TPM_LIB_ERROR ; +if (size_ptr) *size_ptr = response_length; -return tpm_return_code (response); + ret =tpm_return_code (response); + +debug ("TPM response [ret:%d]: " , ret); +for (i =0 ; i < response_length; i++) +debug ("%02x " , ((u8 *)response)[i]); +debug ("\n" ); + +return ret; }int tpm_set_specification (int version)
Signature · 1 line
2.14.1
PATCH 8/18 tpm: handle different buffer sizes
In reply to Miquel RaynalUsual buffer sizes for TPMv1 and TPMv2 are different. Change TPMv1 buffer size definition for that and declare another size for TPMv2 buffers.
--- cmd/tpm.c | 5 +++-- include/tpm.h | 2 ++ lib/tpm.c | 60 +++++++++++++++++++++++++++++------------------------------ 3 files changed, 34 insertions(+), 33 deletions(-)
cmd/tpm.c +3 -2
@@ -323,8 +323,9 @@ static int do_tpm_nv_write_value(cmd_tbl_t *cmdtp, int flag,static int do_tpm_extend (cmd_tbl_t *cmdtp,int flag,int argc,char *const argv[]) { +uint8_t in_digest[TPM1_DIGEST_LENGTH ]; +uint8_t out_digest[TPM1_DIGEST_LENGTH ];uint32_t index, rc; -uint8_t in_digest[20 ], out_digest[20 ];if (argc !=3 )return CMD_RET_USAGE ;
@@ -337,7 +338,7 @@ static int do_tpm_extend(cmd_tbl_t *cmdtp, int flag, rc =tpm_extend (index, in_digest, out_digest);if (!rc) {puts ("PCR value after execution of the command:\n" ); -print_byte_string (out_digest,sizeof (out_digest)); +print_byte_string (out_digest,TPM1_DIGEST_LENGTH ); }return report_return_code (rc);
include/tpm.h +2 -0
@@ -14,6 +14,8 @@*/ #define TPM_HEADER_SIZE 10 +#define TPM1_DIGEST_LENGTH 20 +#define TPM2_DIGEST_LENGTH 32enum tpm_duration {TPM_SHORT =0 ,
lib/tpm.c +29 -31
148 lines not on this page · raw message
Signature · 1 line
2.14.1
PATCH 9/18 tpm: add TPM2_Startup command support
In reply to Miquel RaynalAdd support for the TPM2_Startup command.
Change the command file and the help accordingly.
--- cmd/tpm.c | 9 +++++++-- include/tpm.h | 26 +++++++++++++++++++++++++- lib/tpm.c | 35 +++++++++++++++++++++++++---------- 3 files changed, 57 insertions(+), 13 deletions(-)
cmd/tpm.c +7 -2
@@ -255,6 +255,10 @@ static int do_tpm_startup(cmd_tbl_t *cmdtp, int flag, mode =TPM_ST_STATE ; }else if (!strcasecmp ("TPM_ST_DEACTIVATED" , argv[1 ])) { mode =TPM_ST_DEACTIVATED ; + }else if (!strcasecmp ("TPM2_SU_CLEAR" , argv[1 ])) { + mode =TPM2_SU_CLEAR ; + }else if (!strcasecmp ("TPM2_SU_STATE" , argv[1 ])) { + mode =TPM2_SU_STATE ; }else {printf ("Couldn't recognize mode string: %s\n" , argv[1 ]);return CMD_RET_FAILURE ;
@@ -929,8 +933,9 @@ U_BOOT_CMD(tpm, CONFIG_SYS_MAXARGS, 1, do_tpm," <type> is one of TPM1 (default) or TPM2. This choice impacts the way\n" " other functions will behave.\n" " startup mode\n" -" - Issue TPM_Starup command. <mode> is one of TPM_ST_CLEAR,\n" -" TPM_ST_STATE, and TPM_ST_DEACTIVATED.\n" +" - Issue TPM_Startup command. <mode> is one of:\n" +" * TPM_ST_CLEAR, TPM_ST_STATE, TPM_ST_DEACTIVATED for TPMv1.x.\n" +" * TPM2_SU_CLEAR, TPM2_SU_STATE, for TPMv2.x.\n" "Admin Testing Commands:\n" " self_test_full\n" " - Test all of the TPM capabilities.\n"
include/tpm.h +25 -1
@@ -26,6 +26,11 @@ enum tpm_duration { TPM_DURATION_COUNT, }; +enum tpm2_structures { +TPM2_ST_NO_SESSIONS =0x8001 , +TPM2_ST_SESSIONS =0x8002 , +}; +enum tpm_startup_type {TPM_ST_CLEAR =0x0001 ,TPM_ST_STATE =0x0002 ,
@@ -37,6 +42,25 @@ enum tpm2_startup_types { TPM2_SU_STATE = 0x0001, }; +enum tpm2_command_codes { +TPM2_CC_STARTUP =0x0144 , +TPM2_CC_SELF_TEST =0x0143 , +TPM2_CC_GET_CAPABILITY =0x017A , +TPM2_CC_PCR_READ =0x017E , +TPM2_CC_PCR_EXTEND =0x0182 , +}; + +enum tpm2_return_codes { +TPM2_RC_SUCCESS =0x0000 , +TPM2_RC_HASH =0x0083 ,/* RC_FMT1 */ +TPM2_RC_HANDLE =0x008B , +TPM2_RC_INITIALIZE =0x0100 ,/* RC_VER1 */ +TPM2_RC_DISABLED =0x0120 , +TPM2_RC_TESTING =0x090A ,/* RC_WARN */ +TPM2_RC_REFERENCE_H0 =0x0910 , +TPM2_RC_LOCKOUT =0x0921 , +}; +enum tpm_physical_presence {TPM_PHYSICAL_PRESENCE_HW_DISABLE =0x0200 ,TPM_PHYSICAL_PRESENCE_CMD_DISABLE =0x0100 ,
@@ -445,7 +469,7 @@ int tpm_get_specification(void);* @param mode TPM startup mode * @return return code of the operation */ -uint32_t tpm_startup (enum tpm_startup_type mode); +int tpm_startup (enum tpm_startup_type mode);/** * Issue a TPM_SelfTestFull command.
lib/tpm.c +25 -10
@@ -310,20 +310,35 @@ int tpm_init(void)return tpm_open (dev); } -uint32_t tpm_startup (enum tpm_startup_type mode) +int tpm_startup (enum tpm_startup_type mode) { -const uint8_t command[12 ] = { -0x0 ,0xc1 ,0x0 ,0x0 ,0x0 ,0xc ,0x0 ,0x0 ,0x0 ,0x99 ,0x0 ,0x0 , +const u8 command_v1[12 ] = { +STRINGIFY16 (0xc1 ), +STRINGIFY32 (12 ), +STRINGIFY32 (0x99 ), +STRINGIFY16 (mode), }; -const size_t mode_offset =10 ; -uint8_t buf[COMMAND_BUFFER_SIZE ]; +const u8 command_v2[12 ] = { +STRINGIFY16 (TPM2_ST_NO_SESSIONS ), +STRINGIFY32 (12 ), +STRINGIFY32 (TPM2_CC_STARTUP ), +STRINGIFY16 (mode), + }; +int ret; + +if (!is_tpmv2) +return tpm_sendrecv_command (command_v1,NULL ,NULL ); + + ret =tpm_sendrecv_command (command_v2,NULL ,NULL ); -if (pack_byte_string (buf,sizeof (buf),"sw" , -0 , command,sizeof (command), - mode_offset, mode)) -return TPM_LIB_ERROR ; +/* +* Note TPMv2: STARTUP command will return RC_SUCCESS the first time, +* but will return RC_INITIALIZE otherwise. +*/ +if (ret && ret !=TPM2_RC_INITIALIZE ) +return ret; -return tpm_sendrecv_command (buf,NULL ,NULL ); +return 0 ; }uint32_t tpm_self_test_full (void )
Signature · 1 line
2.14.1
PATCH 10/18 tpm: add TPM2_SelfTest command support
In reply to Miquel RaynalAdd support for the TPM2_Selftest command.
Change the command file and the help accordingly.
--- include/tpm.h | 9 +++++++-- lib/tpm.c | 36 ++++++++++++++++++++++++++++-------- 2 files changed, 35 insertions(+), 10 deletions(-)
include/tpm.h +7 -2
@@ -31,6 +31,11 @@ enum tpm2_structures { TPM2_ST_SESSIONS = 0x8002, }; +enum tpm2_yes_no { +TPMI_YES =1 , +TPMI_NO =0 , +}; +enum tpm_startup_type {TPM_ST_CLEAR =0x0001 ,TPM_ST_STATE =0x0002 ,
@@ -476,14 +481,14 @@ int tpm_startup(enum tpm_startup_type mode);* * @return return code of the operation */ -uint32_t tpm_self_test_full (void ); +int tpm_self_test_full (void );/** * Issue a TPM_ContinueSelfTest command. * * @return return code of the operation */ -uint32_t tpm_continue_self_test (void ); +int tpm_continue_self_test (void );/** * Issue a TPM_NV_DefineSpace command. The implementation is limited
lib/tpm.c +28 -8
@@ -341,20 +341,40 @@ int tpm_startup(enum tpm_startup_type mode)return 0 ; } -uint32_t tpm_self_test_full (void ) +int tpm_self_test_full (void ) { -const uint8_t command[10 ] = { -0x0 ,0xc1 ,0x0 ,0x0 ,0x0 ,0xa ,0x0 ,0x0 ,0x0 ,0x50 , +const u8 command_v1[10 ] = { +STRINGIFY16 (0xc1 ), +STRINGIFY32 (10 ), +STRINGIFY32 (0x50 ), }; -return tpm_sendrecv_command (command,NULL ,NULL ); +const u8 command_v2[12 ] = { +STRINGIFY16 (TPM2_ST_NO_SESSIONS ), +STRINGIFY32 (11 ), +STRINGIFY32 (TPM2_CC_SELF_TEST ), +TPMI_YES , + }; + +return tpm_sendrecv_command (is_tpmv2 ? command_v2 : command_v1,NULL , +NULL ); } -uint32_t tpm_continue_self_test (void ) +int tpm_continue_self_test (void ) { -const uint8_t command[10 ] = { -0x0 ,0xc1 ,0x0 ,0x0 ,0x0 ,0xa ,0x0 ,0x0 ,0x0 ,0x53 , +const u8 command_v1[10 ] = { +STRINGIFY16 (0xc1 ), +STRINGIFY32 (10 ), +STRINGIFY32 (0x53 ), }; -return tpm_sendrecv_command (command,NULL ,NULL ); +const u8 command_v2[12 ] = { +STRINGIFY16 (TPM2_ST_NO_SESSIONS ), +STRINGIFY32 (11 ), +STRINGIFY32 (TPM2_CC_SELF_TEST ), +TPMI_NO , + }; + +return tpm_sendrecv_command (is_tpmv2 ? command_v2 : command_v1,NULL , +NULL ); }uint32_t tpm_nv_define_space (uint32_t index,uint32_t perm,uint32_t size)
Signature · 1 line
2.14.1
PATCH 11/18 tpm: add TPM2_Clear command support
In reply to Miquel RaynalAdd support for the TPM2_Clear command.
Change the command file and the help accordingly.
--- cmd/tpm.c | 29 ++++++++++++++++++++++++++--- cmd/tpm_test.c | 6 +++--- include/tpm.h | 21 +++++++++++++++++---- lib/tpm.c | 42 ++++++++++++++++++++++++++++++++++++++---- 4 files changed, 84 insertions(+), 14 deletions(-)
cmd/tpm.c +26 -3
@@ -454,6 +454,29 @@ static int do_tpm_init(cmd_tbl_t *cmdtp, int flag,return report_return_code (tpm_init ()); } +static int do_tpm_force_clear (cmd_tbl_t *cmdtp,int flag, +int argc,char *const argv[]) +{ +u32 handle =0 ; +const char *pw = (argc <3 ) ?NULL : argv[2 ]; +const ssize_t pw_sz = pw ?strlen (pw) :0 ; + +if (argc <2 || argc >3 ) +return CMD_RET_USAGE ; + +if (pw_sz >TPM2_DIGEST_LENGTH ) +return -EINVAL ; + +if (!strcasecmp ("TPM2_RH_LOCKOUT" , argv[1 ])) + handle =TPM2_RH_LOCKOUT ; +else if (!strcasecmp ("TPM2_RH_PLATFORM" , argv[1 ])) + handle =TPM2_RH_PLATFORM ; +else +return CMD_RET_USAGE ; + +return report_return_code (tpm_force_clear (handle, pw, pw_sz)); +} +#define TPM_COMMAND_NO_ARG (cmd) \ static int do_##cmd(cmd_tbl_t *cmdtp, int flag, \ int argc, char * const argv[]) \
@@ -465,7 +488,6 @@ static int do_##cmd(cmd_tbl_t *cmdtp, int flag, \ TPM_COMMAND_NO_ARG(tpm_self_test_full) TPM_COMMAND_NO_ARG(tpm_continue_self_test) -TPM_COMMAND_NO_ARG(tpm_force_clear) TPM_COMMAND_NO_ARG(tpm_physical_enable) TPM_COMMAND_NO_ARG(tpm_physical_disable)
@@ -951,8 +973,9 @@ U_BOOT_CMD(tpm, CONFIG_SYS_MAXARGS, 1, do_tpm," physical_set_deactivated 0|1\n" " - Set deactivated flag.\n" "Admin Ownership Commands:\n" -" force_clear\n" -" - Issue TPM_ForceClear command.\n" +" force_clear [<type>]\n" +" - Issue TPM_[Force]Clear command, with <type> one of (TPMv2 only):\n" +" * TPM2_RH_LOCKOUT, TPM2_RH_PLATFORM.\n" " tsc_physical_presence flags\n" " - Set TPM device's Physical Presence flags to <flags>.\n" "The Capability Commands:\n"
cmd/tpm_test.c +3 -3
@@ -176,7 +176,7 @@ static int test_fast_enable(void)TPM_CHECK (tpm_get_flags (&disable, &deactivated,NULL ));printf ("\tdisable is %d, deactivated is %d\n" , disable, deactivated);for (i =0 ; i <2 ; i++) { -TPM_CHECK (tpm_force_clear ()); +TPM_CHECK (tpm_force_clear (0 ,NULL ,0 ));TPM_CHECK (tpm_get_flags (&disable, &deactivated,NULL ));printf ("\tdisable is %d, deactivated is %d\n" , disable, deactivated);
@@ -458,7 +458,7 @@ static int test_write_limit(void)TPM_CHECK (TlclStartupIfNeeded ());TPM_CHECK (tpm_self_test_full ());TPM_CHECK (tpm_tsc_physical_presence (PRESENCE )); -TPM_CHECK (tpm_force_clear ()); +TPM_CHECK (tpm_force_clear (0 ,NULL ,0 ));TPM_CHECK (tpm_physical_enable ());TPM_CHECK (tpm_physical_set_deactivated (0 ));
@@ -477,7 +477,7 @@ static int test_write_limit(void) }/* Reset write count */ -TPM_CHECK (tpm_force_clear ()); +TPM_CHECK (tpm_force_clear (0 ,NULL ,0 ));TPM_CHECK (tpm_physical_enable ());TPM_CHECK (tpm_physical_set_deactivated (0 ));
include/tpm.h +17 -4
@@ -43,13 +43,23 @@ enum tpm_startup_type { };enum tpm2_startup_types { -TPM2_SU_CLEAR =0x0000 , -TPM2_SU_STATE =0x0001 , +TPM2_SU_CLEAR =0x0000 , +TPM2_SU_STATE =0x0001 , +}; + +enum tpm2_handles { +TPM2_RH_OWNER =0x40000001 , +TPM2_RS_PW =0x40000009 , +TPM2_RH_LOCKOUT =0x4000000A , +TPM2_RH_ENDORSEMENT =0x4000000B , +TPM2_RH_PLATFORM =0x4000000C , };enum tpm2_command_codes {TPM2_CC_STARTUP =0x0144 ,TPM2_CC_SELF_TEST =0x0143 , +TPM2_CC_CLEAR =0x0126 , +TPM2_CC_CLEARCONTROL =0x0127 ,TPM2_CC_GET_CAPABILITY =0x017A ,TPM2_CC_PCR_READ =0x017E ,TPM2_CC_PCR_EXTEND =0x0182 ,
@@ -567,11 +577,14 @@ uint32_t tpm_tsc_physical_presence(uint16_t presence);uint32_t tpm_read_pubek (void *data,size_t count);/** -* Issue a TPM_ForceClear command. +* Issue a TPM_ForceClear or a TPM2_Clear command. * +* @param handle Handle +* @param pw Password +* @param pw_sz Length of the password * @return return code of the operation */ -uint32_t tpm_force_clear (void ); +int tpm_force_clear (u32 handle,const char *pw,const ssize_t pw_sz);/** * Issue a TPM_PhysicalEnable command.
lib/tpm.c +38 -4
51 lines not on this page · raw message
Signature · 1 line
2.14.1
PATCH 12/18 tpm: rename the _extend() function to be _pcr_event()
In reply to Miquel RaynalThe function currently called _extend() actually does what the specification defines as a _pcr_event(). Rename the function accordingly before implementing the actual _extend() command.
--- cmd/tpm.c | 18 ++++++++++-------- cmd/tpm_test.c | 4 ++-- include/tpm.h | 4 ++-- lib/tpm.c | 2 +- 4 files changed, 15 insertions(+), 13 deletions(-)
cmd/tpm.c +10 -8
@@ -324,8 +324,8 @@ static int do_tpm_nv_write_value(cmd_tbl_t *cmdtp, int flag,return report_return_code (rc); } -static int do_tpm_extend (cmd_tbl_t *cmdtp,int flag, -int argc,char *const argv[]) +static int do_tpm_pcr_event (cmd_tbl_t *cmdtp,int flag, +int argc,char *const argv[]) {uint8_t in_digest[TPM1_DIGEST_LENGTH ];uint8_t out_digest[TPM1_DIGEST_LENGTH ];
@@ -333,13 +333,14 @@ static int do_tpm_extend(cmd_tbl_t *cmdtp, int flag,if (argc !=3 )return CMD_RET_USAGE ; + index =simple_strtoul (argv[1 ],NULL ,0 );if (!parse_byte_string (argv[2 ], in_digest,NULL )) {printf ("Couldn't parse byte string %s\n" , argv[2 ]);return CMD_RET_FAILURE ; } - rc =tpm_extend (index, in_digest, out_digest); + rc =tpm_pcr_event (index, in_digest, out_digest);if (!rc) {puts ("PCR value after execution of the command:\n" );print_byte_string (out_digest,TPM1_DIGEST_LENGTH );
@@ -887,8 +888,8 @@ static cmd_tbl_t tpm_commands[] = { do_tpm_nv_read_value, "", ""),U_BOOT_CMD_MKENT (nv_write_value,0 ,1 , do_tpm_nv_write_value,"" ,"" ), -U_BOOT_CMD_MKENT (extend,0 ,1 , - do_tpm_extend,"" ,"" ), +U_BOOT_CMD_MKENT (pcr_event,0 ,1 , + do_tpm_pcr_event,"" ,"" ),U_BOOT_CMD_MKENT (pcr_read,0 ,1 , do_tpm_pcr_read,"" ,"" ), U_BOOT_CMD_MKENT(tsc_physical_presence, 0, 1,
@@ -1019,9 +1020,10 @@ U_BOOT_CMD(tpm, CONFIG_SYS_MAXARGS, 1, do_tpm," - Read <count> bytes of the public endorsement key to memory\n" " address <addr>\n" "Integrity Collection and Reporting Commands:\n" -" extend index digest_hex_string\n" -" - Add a new measurement to a PCR. Update PCR <index> with the 20-bytes\n" -" <digest_hex_string>\n" +" pcr_event <index> <digest_in> <digest_out>\n" +" - Add a new measurement to a PCR. Update PCR <index> with\n" +" <digest_in>. It must be a 20 byte digest for TPMv1 or a SHA256\n" +" digest of 32 bytes for TPMv2. Value of the PCR is given at <digest_out>\n" " pcr_read index addr count\n" " - Read <count> bytes from PCR <index> to memory address <addr>.\n" #ifdef CONFIG_TPM_AUTH_SESSIONS
cmd/tpm_test.c +2 -2
@@ -104,7 +104,7 @@ static int test_early_extend(void)tpm_init ();TPM_CHECK (tpm_startup (TPM_ST_CLEAR ));TPM_CHECK (tpm_continue_self_test ()); -TPM_CHECK (tpm_extend (1 , value_in, value_out)); +TPM_CHECK (tpm_pcr_event (1 , value_in, value_out));printf ("done\n" );return 0 ; }
@@ -439,7 +439,7 @@ static int test_timing(void)TTPM_CHECK (tpm_tsc_physical_presence (PRESENCE ),100 );TTPM_CHECK (tpm_nv_write_value (INDEX0 , (uint8_t *)&x,sizeof (x)),100 );TTPM_CHECK (tpm_nv_read_value (INDEX0 , (uint8_t *)&x,sizeof (x)),100 ); -TTPM_CHECK (tpm_extend (0 , in, out),200 ); +TTPM_CHECK (tpm_pcr_event (0 , in, out),200 );TTPM_CHECK (tpm_set_global_lock (),50 );TTPM_CHECK (tpm_tsc_physical_presence (PHYS_PRESENCE ),100 );printf ("done\n" );
include/tpm.h +2 -2
@@ -537,7 +537,7 @@ uint32_t tpm_nv_read_value(uint32_t index, void *data, uint32_t count);uint32_t tpm_nv_write_value (uint32_t index,const void *data,uint32_t length);/** -* Issue a TPM_Extend command. +* Issue a TPM_PCR_Event command. * * @param index index of the PCR * @param in_digest 160-bit value representing the event to be
@@ -546,7 +546,7 @@ uint32_t tpm_nv_write_value(uint32_t index, const void *data, uint32_t length);* command * @return return code of the operation */ -uint32_t tpm_extend (uint32_t index,const void *in_digest,void *out_digest); +int tpm_pcr_event (u32 index,const void *in_digest,void *out_digest);/** * Issue a TPM_PCRRead command.
lib/tpm.c +1 -1
@@ -493,7 +493,7 @@ uint32_t tpm_nv_write_value(uint32_t index, const void *data, uint32_t length)return 0 ; } -uint32_t tpm_extend (uint32_t index,const void *in_digest,void *out_digest) +int tpm_pcr_event (u32 index,const void *in_digest,void *out_digest) {const uint8_t command[34 ] = {0x0 ,0xc1 ,0x0 ,0x0 ,0x0 ,0x22 ,0x0 ,0x0 ,0x0 ,0x14 ,
Signature · 1 line
2.14.1
PATCH 13/18 tpm: add TPM2_PCR_Extend command support
In reply to Miquel RaynalAdd support for the TPM2_PCR_Extend command.
Change the command file and the help accordingly.
--- cmd/tpm.c | 18 ++++++++++++++++++ include/tpm.h | 18 ++++++++++++++++++ lib/tpm.c | 41 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 77 insertions(+)
cmd/tpm.c +18 -0
@@ -349,6 +349,18 @@ static int do_tpm_pcr_event(cmd_tbl_t *cmdtp, int flag,return report_return_code (rc); } +static int do_tpm_pcr_extend (cmd_tbl_t *cmdtp,int flag, +int argc,char *const argv[]) +{ +u32 index =simple_strtoul (argv[1 ],NULL ,0 ); +void *digest = (void *)simple_strtoul (argv[2 ],NULL ,0 ); + +if (argc !=3 ) +return CMD_RET_USAGE ; + +return report_return_code (tpm2_pcr_extend (index, digest)); +} +static int do_tpm_pcr_read (cmd_tbl_t *cmdtp,int flag,int argc,char *const argv[]) {
@@ -890,6 +902,8 @@ static cmd_tbl_t tpm_commands[] = { do_tpm_nv_write_value, "", ""),U_BOOT_CMD_MKENT (pcr_event,0 ,1 , do_tpm_pcr_event,"" ,"" ), +U_BOOT_CMD_MKENT (pcr_extend,0 ,1 , + do_tpm_pcr_extend,"" ,"" ),U_BOOT_CMD_MKENT (pcr_read,0 ,1 , do_tpm_pcr_read,"" ,"" ), U_BOOT_CMD_MKENT(tsc_physical_presence, 0, 1,
@@ -1026,6 +1040,10 @@ U_BOOT_CMD(tpm, CONFIG_SYS_MAXARGS, 1, do_tpm," digest of 32 bytes for TPMv2. Value of the PCR is given at <digest_out>\n" " pcr_read index addr count\n" " - Read <count> bytes from PCR <index> to memory address <addr>.\n" +" pcr_extend index <digest_in>\n" +" - Add a new measurement to a PCR. Update PCR <index> with\n" +" <digest_in>. It must be a 20 byte digest for TPMv1 or a SHA256\n" +" digest of 32 bytes for TPMv2.\n" #ifdef CONFIG_TPM_AUTH_SESSIONS"Authorization Sessions\n" " oiap\n"
include/tpm.h +18 -0
@@ -76,6 +76,14 @@ enum tpm2_return_codes { TPM2_RC_LOCKOUT = 0x0921, }; +enum tpm_algorithms { +TPM2_ALG_XOR =0x0A , +TPM2_ALG_SHA256 =0x0B , +TPM2_ALG_SHA384 =0x0C , +TPM2_ALG_SHA512 =0x0D , +TPM2_ALG_NULL =0x10 , +}; +enum tpm_physical_presence {TPM_PHYSICAL_PRESENCE_HW_DISABLE =0x0200 ,TPM_PHYSICAL_PRESENCE_CMD_DISABLE =0x0100 ,
@@ -548,6 +556,16 @@ uint32_t tpm_nv_write_value(uint32_t index, const void *data, uint32_t length);*/ int tpm_pcr_event (u32 index,const void *in_digest,void *out_digest); +/** +* Issue a TPM_PCR_Extend command. +* +* @param index Index of the PCR +* @param digest Value representing the event to be recorded +* +* @return return code of the operation +*/ +int tpm2_pcr_extend (u32 index,const uint8_t *digest); +/** * Issue a TPM_PCRRead command. *
lib/tpm.c +41 -0
47 lines not on this page · raw message
Signature · 1 line
2.14.1
PATCH 14/18 tpm: add TPM2_PCR_Read command support
In reply to Miquel RaynalAdd support for the TPM2_PCR_Read command.
Change the command file and the help accordingly.
--- cmd/tpm.c | 23 ++++++++++++++--------- include/tpm.h | 4 ++-- lib/tpm.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 71 insertions(+), 12 deletions(-)
cmd/tpm.c +14 -9
@@ -362,21 +362,25 @@ static int do_tpm_pcr_extend(cmd_tbl_t *cmdtp, int flag, }static int do_tpm_pcr_read (cmd_tbl_t *cmdtp,int flag, -int argc,char *const argv[]) +int argc,char *const argv[]) { -uint32_t index, count, rc; +bool is_tpmv2 = (tpm_get_specification () ==2 ); +u32 index, rc; +unsigned int updates;void *data; -if (argc !=4 ) +if (argc !=3 )return CMD_RET_USAGE ; + index =simple_strtoul (argv[1 ],NULL ,0 ); data = (void *)simple_strtoul (argv[2 ],NULL ,0 ); - count =simple_strtoul (argv[3 ],NULL ,0 ); - rc =tpm_pcr_read (index, data, count); + rc =tpm_pcr_read (index, data, &updates);if (!rc) { -puts ("Named PCR content:\n" ); -print_byte_string (data, count); +printf ("Named PCR %u content (known updates: %d):\n" , index, + is_tpmv2 ? updates :-1 ); +print_byte_string (data, !is_tpmv2 ?TPM1_DIGEST_LENGTH : +TPM2_DIGEST_LENGTH ); }return report_return_code (rc);
@@ -1038,12 +1042,13 @@ U_BOOT_CMD(tpm, CONFIG_SYS_MAXARGS, 1, do_tpm," - Add a new measurement to a PCR. Update PCR <index> with\n" " <digest_in>. It must be a 20 byte digest for TPMv1 or a SHA256\n" " digest of 32 bytes for TPMv2. Value of the PCR is given at <digest_out>\n" -" pcr_read index addr count\n" -" - Read <count> bytes from PCR <index> to memory address <addr>.\n" " pcr_extend index <digest_in>\n" " - Add a new measurement to a PCR. Update PCR <index> with\n" " <digest_in>. It must be a 20 byte digest for TPMv1 or a SHA256\n" " digest of 32 bytes for TPMv2.\n" +" pcr_read <index> <digest_in>\n" +" - Read PCR <index> to memory address <digest_in> (20B with TPMv1, 64B with\n" +" TPMv2).\n" #ifdef CONFIG_TPM_AUTH_SESSIONS"Authorization Sessions\n" " oiap\n"
include/tpm.h +2 -2
@@ -571,10 +571,10 @@ int tpm2_pcr_extend(u32 index, const uint8_t *digest);* * @param index index of the PCR * @param data output buffer for contents of the named PCR -* @param count size of output buffer +* @param updates optional out parameter: number of updates for this PCR * @return return code of the operation */ -uint32_t tpm_pcr_read (uint32_t index,void *data,size_t count); +int tpm_pcr_read (u32 index,void *data,unsigned int *updates);/** * Issue a TSC_PhysicalPresence command. TPM physical presence flag
lib/tpm.c +55 -1
68 lines not on this page · raw message
Signature · 1 line
2.14.1
PATCH 15/18 tpm: add TPM2_GetCapability command support
In reply to Miquel RaynalAdd support for the TPM2_GetCapability command.
Change the command file and the help accordingly.
--- cmd/tpm.c | 31 ++++++++++++++++++++----------- include/tpm.h | 14 +++++++------- lib/tpm.c | 39 +++++++++++++++++++++++++++++++++++++-- 3 files changed, 64 insertions(+), 20 deletions(-)
cmd/tpm.c +20 -11
@@ -433,21 +433,30 @@ static int do_tpm_physical_set_deactivated(cmd_tbl_t *cmdtp, int flag,static int do_tpm_get_capability (cmd_tbl_t *cmdtp,int flag,int argc,char *const argv[]) { -uint32_t cap_area, sub_cap, rc; -void *cap; +u32 capability, property, rc; +u8 *data;size_t count; +int i, j;if (argc !=5 )return CMD_RET_USAGE ; - cap_area =simple_strtoul (argv[1 ],NULL ,0 ); - sub_cap =simple_strtoul (argv[2 ],NULL ,0 ); - cap = (void *)simple_strtoul (argv[3 ],NULL ,0 ); + capability =simple_strtoul (argv[1 ],NULL ,0 ); + property =simple_strtoul (argv[2 ],NULL ,0 ); + data = (void *)simple_strtoul (argv[3 ],NULL ,0 ); count =simple_strtoul (argv[4 ],NULL ,0 ); - rc =tpm_get_capability (cap_area, sub_cap, cap, count); + rc =tpm_get_capability (capability, property, data, count);if (!rc) { -puts ("capability information:\n" ); -print_byte_string (cap, count); +printf ("Capabilities read from TPM:\n" ); +for (i =0 ; i < count; i++) { +printf ("Property 0x" ); +for (j =0 ; j <4 ; j++) +printf ("%02x" , data[(i *8 ) + j]); +printf (": 0x" ); +for (j =4 ; j <8 ; j++) +printf ("%02x" , data[(i *8 ) + j]); +printf ("\n" ); + } }return report_return_code (rc);
@@ -998,9 +1007,9 @@ U_BOOT_CMD(tpm, CONFIG_SYS_MAXARGS, 1, do_tpm," tsc_physical_presence flags\n" " - Set TPM device's Physical Presence flags to <flags>.\n" "The Capability Commands:\n" -" get_capability cap_area sub_cap addr count\n" -" - Read <count> bytes of TPM capability indexed by <cap_area> and\n" -" <sub_cap> to memory address <addr>.\n" +" get_capability <cap_area|capability> <sub_cap|property> <addr> <count>\n" +" - Read <count> bytes of TPM capability indexed by <cap_area|capability>\n" +" and <sub_cap|property> to memory address <addr>.\n"#if defined(CONFIG_TPM_FLUSH_RESOURCES ) || defined(CONFIG_TPM_LIST_RESOURCES ) "Resource management functions\n"#endif
include/tpm.h +7 -7
@@ -628,17 +628,17 @@ uint32_t tpm_physical_set_deactivated(uint8_t state);/** * Issue a TPM_GetCapability command. This implementation is limited -* to query sub_cap index that is 4-byte wide. +* to query property index that is 4-byte wide. * -* @param cap_area partition of capabilities -* @param sub_cap further definition of capability, which is +* @param capability partition of capabilities +* @param property further definition of capability, which is * limited to be 4-byte wide -* @param cap output buffer for capability information -* @param count size of ouput buffer +* @param buf output buffer for capability information +* @param propertycount size of output buffer * @return return code of the operation */ -uint32_t tpm_get_capability (uint32_t cap_area,uint32_t sub_cap, -void *cap,size_t count); +int tpm_get_capability (u32 capability,u32 property,void *buf, +size_t property_count);/** * Issue a TPM_FlushSpecific command for a AUTH ressource.
lib/tpm.c +37 -2
@@ -789,8 +789,7 @@ uint32_t tpm_physical_set_deactivated(uint8_t state)return tpm_sendrecv_command (buf,NULL ,NULL ); } -uint32_t tpm_get_capability (uint32_t cap_area,uint32_t sub_cap, -void *cap,size_t count) +int tpm1_get_capability (u32 cap_area,u32 sub_cap,void *cap,size_t count) {const uint8_t command[22 ] = {0x0 ,0xc1 ,/* TPM_TAG */
@@ -829,6 +828,42 @@ uint32_t tpm_get_capability(uint32_t cap_area, uint32_t sub_cap,return 0 ; } +int tpm2_get_capability (u32 capability,u32 property,void *buf, +size_t property_count) +{ +u8 command_v2[COMMAND_BUFFER_SIZE ] = { +STRINGIFY16 (TPM2_ST_NO_SESSIONS ),/* TAG */ +STRINGIFY32 (22 ),/* Command size */ +STRINGIFY32 (TPM2_CC_GET_CAPABILITY ),/* Command code */ + +STRINGIFY32 (capability),/* Capability */ +STRINGIFY32 (property),/* Property */ +STRINGIFY32 (property_count),/* Property count */ + }; +u8 response[COMMAND_BUFFER_SIZE ]; +size_t response_len =COMMAND_BUFFER_SIZE ; +int ret; + + ret =tpm_sendrecv_command (command_v2, response, &response_len); +if (ret) +return ret; + +memcpy (buf, &response[19 ], response_len -19 ); + +return 0 ; +} + +int tpm_get_capability (u32 capability,u32 property,void *buf, +size_t property_count) +{ +if (!is_tpmv2) +return tpm1_get_capability (capability, property, buf, + property_count); +else +return tpm2_get_capability (capability, property, buf, + property_count); +} +uint32_t tpm_get_permanent_flags (struct tpm_permanent_flags *pflags) {const uint8_t command[22 ] = {
Signature · 1 line
2.14.1
PATCH 16/18 tpm: add dictionary attack mitigation commands support
In reply to Miquel RaynalAdd support for the TPM2_DictionaryAttackParameters and TPM2_DictionaryAttackLockReset commands.
Change the command file and the help accordingly.
--- cmd/tpm.c | 69 +++++++++++++++++++++++++++++++++++++++++++++ include/tpm.h | 26 +++++++++++++++++ lib/tpm.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 184 insertions(+)
cmd/tpm.c +69 -0
@@ -480,6 +480,58 @@ static int do_tpm_init(cmd_tbl_t *cmdtp, int flag,return report_return_code (tpm_init ()); } +static int do_tpm_dam_reset_counter (cmd_tbl_t *cmdtp,int flag, +int argc,char *const argv[]) +{ +const char *pw = (argc <2 ) ?NULL : argv[1 ]; +const ssize_t pw_sz = pw ?strlen (pw) :0 ; + +if (argc >2 ) +return CMD_RET_USAGE ; + +if (pw_sz >TPM2_DIGEST_LENGTH ) +return -EINVAL ; + +return report_return_code (tpm2_dam_reset_counter (pw, pw_sz)); +} + +static int do_tpm_dam_set_parameters (cmd_tbl_t *cmdtp,int flag, +int argc,char *const argv[]) +{ +const char *pw = (argc <5 ) ?NULL : argv[4 ]; +const ssize_t pw_sz = pw ?strlen (pw) :0 ; +/* +* No Dictionary Attack Mitigation (DAM) means: +* maxtries = 0xFFFFFFFF, recovery_time = 0, lockout_recovery = 1 +*/ +unsigned long int max_tries; +unsigned long int recovery_time; +unsigned long int lockout_recovery; + +if (argc <4 || argc >5 ) +return CMD_RET_USAGE ; + +if (pw_sz >TPM2_DIGEST_LENGTH ) +return -EINVAL ; + +if (strict_strtoul (argv[1 ],0 , &max_tries)) +return CMD_RET_USAGE ; + +if (strict_strtoul (argv[2 ],0 , &recovery_time)) +return CMD_RET_USAGE ; + +if (strict_strtoul (argv[3 ],0 , &lockout_recovery)) +return CMD_RET_USAGE ; + +debug ("Changing dictionary attack parameters:\n" ); +debug ("- maxTries: %lu\n- recoveryTime: %lu\n- lockoutRecovery: %lu\n" , + max_tries, recovery_time, lockout_recovery); + +return report_return_code (tpm2_dam_set_parameters (pw, pw_sz, max_tries, + recovery_time, + lockout_recovery)); +} +static int do_tpm_force_clear (cmd_tbl_t *cmdtp,int flag,int argc,char *const argv[]) {
@@ -901,6 +953,10 @@ static cmd_tbl_t tpm_commands[] = { do_tpm_self_test_full, "", ""),U_BOOT_CMD_MKENT (continue_self_test,0 ,1 , do_tpm_continue_self_test,"" ,"" ), +U_BOOT_CMD_MKENT (dam_reset_counter,0 ,1 , + do_tpm_dam_reset_counter,"" ,"" ), +U_BOOT_CMD_MKENT (dam_set_parameters,0 ,1 , + do_tpm_dam_set_parameters,"" ,"" ),U_BOOT_CMD_MKENT (force_clear,0 ,1 , do_tpm_force_clear,"" ,"" ), U_BOOT_CMD_MKENT(physical_enable, 0, 1,
@@ -1010,6 +1066,19 @@ U_BOOT_CMD(tpm, CONFIG_SYS_MAXARGS, 1, do_tpm," get_capability <cap_area|capability> <sub_cap|property> <addr> <count>\n" " - Read <count> bytes of TPM capability indexed by <cap_area|capability>\n" " and <sub_cap|property> to memory address <addr>.\n" +"Lockout/Dictionary attack Commands:\n" +" dam_reset_counter [<password>]\n" +" - If the TPM is not in a LOCKOUT state, reset the internal error\n" +" counter (TPMv2 only)\n" +" dam_set_parameters <maxTries> <recoveryTime> <lockoutRecovery> [<password>]\n" +" - If the TPM is not in a LOCKOUT state, set the dictionary attack\n" +" parameters:\n" +" * maxTries: maximum number of failures before lockout.\n" +" 0 means always locking.\n" +" * recoveryTime: time before decrementation of the error counter,\n" +" 0 means no lockout.\n" +" * lockoutRecovery: time of a lockout (before the next try)\n" +" 0 means a reboot is needed.\n"#if defined(CONFIG_TPM_FLUSH_RESOURCES ) || defined(CONFIG_TPM_LIST_RESOURCES ) "Resource management functions\n"#endif
include/tpm.h +26 -0
@@ -60,6 +60,8 @@ enum tpm2_command_codes {TPM2_CC_SELF_TEST =0x0143 ,TPM2_CC_CLEAR =0x0126 ,TPM2_CC_CLEARCONTROL =0x0127 , +TPM2_CC_DAM_RESET =0x0139 , +TPM2_CC_DAM_PARAMETERS =0x013A ,TPM2_CC_GET_CAPABILITY =0x017A ,TPM2_CC_PCR_READ =0x017E , TPM2_CC_PCR_EXTEND = 0x0182,
@@ -594,6 +596,30 @@ uint32_t tpm_tsc_physical_presence(uint16_t presence);*/ uint32_t tpm_read_pubek (void *data,size_t count); +/** +* Issue a TPM2_DictionaryAttackLockReset command. +* +* @param pw Password +* @param pw_sz Length of the password +* @return return code of the operation +*/ +int tpm2_dam_reset_counter (const char *pw,const ssize_t pw_sz); + +/** +* Issue a TPM2_DictionaryAttackLockParameters command. +* +* @param pw Password +* @param pw_sz Length of the password +* @param max_tries Count of authorizations before lockout +* @param recovery_time Time before decrementation of the failure count +* @param lockout_recovery Time to wait after a lockout +* @return return code of the operation +*/ +int tpm2_dam_set_parameters (const char *pw,const ssize_t pw_sz, +unsigned int max_tries, +unsigned int recovery_time, +unsigned int lockout_recovery); +/** * Issue a TPM_ForceClear or a TPM2_Clear command. *
lib/tpm.c +89 -0
95 lines not on this page · raw message
Signature · 1 line
2.14.1
PATCH 17/18 tpm: add TPM2_HierarchyChangeAuth command support
In reply to Miquel RaynalAdd support for the TPM2_HierarchyChangeAuth command.
Change the command file and the help accordingly.
--- cmd/tpm.c | 34 ++++++++++++++++++++++++++++++++++ include/tpm.h | 14 ++++++++++++++ lib/tpm.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 95 insertions(+)
cmd/tpm.c +34 -0
@@ -555,6 +555,36 @@ static int do_tpm_force_clear(cmd_tbl_t *cmdtp, int flag,return report_return_code (tpm_force_clear (handle, pw, pw_sz)); } +static int do_tpm_change_auth (cmd_tbl_t *cmdtp,int flag, +int argc,char *const argv[]) +{ +u32 handle; +const char *newpw = argv[2 ]; +const char *oldpw = (argc ==3 ) ?NULL : argv[3 ]; +const ssize_t newpw_sz =strlen (newpw); +const ssize_t oldpw_sz = oldpw ?strlen (oldpw) :0 ; + +if (argc <3 || argc >4 ) +return CMD_RET_USAGE ; + +if (newpw_sz >TPM2_DIGEST_LENGTH || oldpw_sz >TPM2_DIGEST_LENGTH ) +return -EINVAL ; + +if (!strcasecmp ("TPM2_RH_LOCKOUT" , argv[1 ])) + handle =TPM2_RH_LOCKOUT ; +else if (!strcasecmp ("TPM2_RH_ENDORSEMENT" , argv[1 ])) + handle =TPM2_RH_ENDORSEMENT ; +else if (!strcasecmp ("TPM2_RH_OWNER" , argv[1 ])) + handle =TPM2_RH_OWNER ; +else if (!strcasecmp ("TPM2_RH_PLATFORM" , argv[1 ])) + handle =TPM2_RH_PLATFORM ; +else +return CMD_RET_USAGE ; + +return report_return_code (tpm2_change_auth (handle, newpw, newpw_sz, + oldpw, oldpw_sz)); +} +#define TPM_COMMAND_NO_ARG (cmd) \ static int do_##cmd(cmd_tbl_t *cmdtp, int flag, \ int argc, char * const argv[]) \
@@ -959,6 +989,8 @@ static cmd_tbl_t tpm_commands[] = { do_tpm_dam_set_parameters, "", ""),U_BOOT_CMD_MKENT (force_clear,0 ,1 , do_tpm_force_clear,"" ,"" ), +U_BOOT_CMD_MKENT (change_auth,0 ,1 , + do_tpm_change_auth,"" ,"" ),U_BOOT_CMD_MKENT (physical_enable,0 ,1 , do_tpm_physical_enable,"" ,"" ), U_BOOT_CMD_MKENT(physical_disable, 0, 1,
@@ -1060,6 +1092,8 @@ U_BOOT_CMD(tpm, CONFIG_SYS_MAXARGS, 1, do_tpm," force_clear [<type>]\n" " - Issue TPM_[Force]Clear command, with <type> one of (TPMv2 only):\n" " * TPM2_RH_LOCKOUT, TPM2_RH_PLATFORM.\n" +" change_auth <new_pw> [<old_pw>]\n" +" - Change the hierarchy authorizations (TPMv2 only).\n" " tsc_physical_presence flags\n" " - Set TPM device's Physical Presence flags to <flags>.\n" "The Capability Commands:\n"
include/tpm.h +14 -0
@@ -60,6 +60,7 @@ enum tpm2_command_codes {TPM2_CC_SELF_TEST =0x0143 ,TPM2_CC_CLEAR =0x0126 ,TPM2_CC_CLEARCONTROL =0x0127 , +TPM2_CC_HIERCHANGEAUTH =0x0129 ,TPM2_CC_DAM_RESET =0x0139 ,TPM2_CC_DAM_PARAMETERS =0x013A , TPM2_CC_GET_CAPABILITY = 0x017A,
@@ -630,6 +631,19 @@ int tpm2_dam_set_parameters(const char *pw, const ssize_t pw_sz,*/ int tpm_force_clear (u32 handle,const char *pw,const ssize_t pw_sz); +/** +* Issue a TPM2_HierarchyChangeAuthorization command. +* +* @param handle Handle +* @param newpw New password +* @param newpw_sz Length of the new password +* @param oldpw Old password +* @param oldpw_sz Length of the old password +* @return return code of the operation +*/ +int tpm2_change_auth (u32 handle,const char *newpw,const ssize_t newpw_sz, +const char *oldpw,const ssize_t oldpw_sz); +/** * Issue a TPM_PhysicalEnable command. *
lib/tpm.c +47 -0
53 lines not on this page · raw message
Signature · 1 line
2.14.1
PATCH 18/18 tpm: add PCR authentication commands support
In reply to Miquel RaynalAdd support for the TPM2_PCR_SetAuthPolicy andTPM2_PCR_SetAuthValue commands.
Change the command file and the help accordingly.
Note: These commands could not be tested because the TPMs available do not support them, however they could be useful for someone else. The user is warned by the command help.
--- cmd/tpm.c | 49 +++++++++++++++++++++++++++ include/tpm.h | 29 ++++++++++++++++ lib/tpm.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 184 insertions(+)
cmd/tpm.c +49 -0
@@ -349,6 +349,43 @@ static int do_tpm_pcr_event(cmd_tbl_t *cmdtp, int flag,return report_return_code (rc); } +static int do_tpm_pcr_setauthpolicy (cmd_tbl_t *cmdtp,int flag, +int argc,char *const argv[]) +{ +u32 index =simple_strtoul (argv[1 ],NULL ,0 ); +char *key = argv[2 ]; +const char *pw = (argc <4 ) ?NULL : argv[3 ]; +const ssize_t pw_sz = pw ?strlen (pw) :0 ; + +if (strlen (key) !=TPM2_DIGEST_LENGTH ) +return -EINVAL ; + +if (argc <3 || argc >4 ) +return CMD_RET_USAGE ; + +return report_return_code (tpm2_pcr_setauthpolicy (pw, pw_sz, index, + key)); +} + +static int do_tpm_pcr_setauthvalue (cmd_tbl_t *cmdtp,int flag, +int argc,char *const argv[]) +{ +u32 index =simple_strtoul (argv[1 ],NULL ,0 ); +char *key = argv[2 ]; +const ssize_t key_sz =strlen (key); +const char *pw = (argc <4 ) ?NULL : argv[3 ]; +const ssize_t pw_sz = pw ?strlen (pw) :0 ; + +if (strlen (key) !=TPM2_DIGEST_LENGTH ) +return -EINVAL ; + +if (argc <3 || argc >4 ) +return CMD_RET_USAGE ; + +return report_return_code (tpm2_pcr_setauthvalue (pw, pw_sz, index, + key, key_sz)); +} +static int do_tpm_pcr_extend (cmd_tbl_t *cmdtp,int flag,int argc,char *const argv[]) {
@@ -1003,6 +1040,10 @@ static cmd_tbl_t tpm_commands[] = { do_tpm_nv_write_value, "", ""),U_BOOT_CMD_MKENT (pcr_event,0 ,1 , do_tpm_pcr_event,"" ,"" ), +U_BOOT_CMD_MKENT (pcr_setauthpolicy,0 ,1 , + do_tpm_pcr_setauthpolicy,"" ,"" ), +U_BOOT_CMD_MKENT (pcr_setauthvalue,0 ,1 , + do_tpm_pcr_setauthvalue,"" ,"" ),U_BOOT_CMD_MKENT (pcr_extend,0 ,1 , do_tpm_pcr_extend,"" ,"" ), U_BOOT_CMD_MKENT(pcr_read, 0, 1,
@@ -1150,6 +1191,14 @@ U_BOOT_CMD(tpm, CONFIG_SYS_MAXARGS, 1, do_tpm," - Read <count> bytes of the public endorsement key to memory\n" " address <addr>\n" "Integrity Collection and Reporting Commands:\n" +" pcr_setauthpolicy <index> <key> <pw>\n" +" - Change the <key> to access <index> PCR. <pw> is for the platform\n" +" hierarchy and may be empty.\n" +" /!\\WARNING: untested function, use at your own risks !\n" +" pcr_setauthvalue <index> <key> <pw>\n" +" - Change the <key> to access <index> PCR. <pw> is for the platform\n" +" hierarchy and may be empty.\n" +" /!\\WARNING: untested function, use at your own risks !\n" " pcr_event <index> <digest_in> <digest_out>\n" " - Add a new measurement to a PCR. Update PCR <index> with\n" " <digest_in>. It must be a 20 byte digest for TPMv1 or a SHA256\n"
include/tpm.h +29 -0
@@ -61,11 +61,13 @@ enum tpm2_command_codes {TPM2_CC_CLEAR =0x0126 ,TPM2_CC_CLEARCONTROL =0x0127 ,TPM2_CC_HIERCHANGEAUTH =0x0129 , +TPM2_CC_PCR_SETAUTHPOL =0x012C ,TPM2_CC_DAM_RESET =0x0139 ,TPM2_CC_DAM_PARAMETERS =0x013A ,TPM2_CC_GET_CAPABILITY =0x017A ,TPM2_CC_PCR_READ =0x017E ,TPM2_CC_PCR_EXTEND =0x0182 , + TPM2_CC_PCR_SETAUTHVAL = 0x0183, }; enum tpm2_return_codes {
@@ -559,6 +561,33 @@ uint32_t tpm_nv_write_value(uint32_t index, const void *data, uint32_t length);*/ int tpm_pcr_event (u32 index,const void *in_digest,void *out_digest); +/** +* Issue a TPM_PCR_SetAuthPolicy command. +* +* @param pw Platform password +* @param pw_sz Length of the password +* @param index Index of the PCR +* @param digest New key to access the PCR +* +* @return return code of the operation +*/ +int tpm2_pcr_setauthpolicy (const char *pw,const ssize_t pw_sz,u32 index, +const char *key); + +/** +* Issue a TPM_PCR_SetAuthValue command. +* +* @param pw Platform password +* @param pw_sz Length of the password +* @param index Index of the PCR +* @param digest New key to access the PCR +* @param key_sz Length of the new key +* +* @return return code of the operation +*/ +int tpm2_pcr_setauthvalue (const char *pw,const ssize_t pw_sz,u32 index, +const char *key,const ssize_t key_sz); +/** * Issue a TPM_PCR_Extend command. *
lib/tpm.c +106 -0
112 lines not on this page · raw message
Signature · 1 line
2.14.1
cover Introduce SPI TPM v2.0 support
In reply to Miquel RaynalQuoted 8 lines · Miquel Raynal
Current U-Boot supports TPM v1.2 specification. The new specification (v2.0) is not backward compatible and renames/introduces several functions.
This series introduces a new SPI driver following the TPM v2.0 specification. It has been tested on a ST TPM but should be usable with others v2.0 compliant chips.
Quoted 5 lines
Then, basic functionalities are introduced one by one for the v2.0 specification. The INIT command now can receive a parameter to distinguish further TPMv1/TPMv2 commands. After that, the library itself will know which one is pertinent and will return a special error if the desired command is not supported for the selected specification.
Thanks for doing all of this. Can you please enable this feature on sandbox and/or an x86 QEMU variant where I assume we could also then setup automated testing?
Signature · 8 lines
Tom -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: not available URL: <http://lists.denx.de/pipermail/u-boot/attachments/20180308/86ea4e74/attachment.sig>
cover Introduce SPI TPM v2.0 support
Hi Tom,
Quoted 16 lines · Tom Rini
Quoted 8 lines · Miquel Raynal
Current U-Boot supports TPM v1.2 specification. The new specification (v2.0) is not backward compatible and renames/introduces several functions.
This series introduces a new SPI driver following the TPM v2.0 specification. It has been tested on a ST TPM but should be usable with others v2.0 compliant chips.
Quoted 5 lines
Then, basic functionalities are introduced one by one for the v2.0 specification. The INIT command now can receive a parameter to distinguish further TPMv1/TPMv2 commands. After that, the library itself will know which one is pertinent and will return a special error if the desired command is not supported for the selected specification.
Quoted 4 lines
Thanks for doing all of this. Can you please enable this feature on sandbox and/or an x86 QEMU variant where I assume we could also then setup automated testing?
Not sure I understand your request correctly: the TPM commands are already available in the sandbox (I don't see what I could add), I just extended the current set of commands.
However, even with these commands, we won't be able to test them in a sandbox unless with an actual device.
I probably miss something, can you explain a bit more what you would like?
Thank you,
Miquèl
Signature · 3 lines
Miquel Raynal, Bootlin (formerly Free Electrons) Embedded Linux and Kernel engineering https://bootlin.com
cover Introduce SPI TPM v2.0 support
Quoted 29 lines · Miquel Raynal
Hi Tom,
Quoted 16 lines · Tom Rini
Quoted 8 lines · Miquel Raynal
Current U-Boot supports TPM v1.2 specification. The new specification (v2.0) is not backward compatible and renames/introduces several functions.
This series introduces a new SPI driver following the TPM v2.0 specification. It has been tested on a ST TPM but should be usable with others v2.0 compliant chips.
Quoted 5 lines
Then, basic functionalities are introduced one by one for the v2.0 specification. The INIT command now can receive a parameter to distinguish further TPMv1/TPMv2 commands. After that, the library itself will know which one is pertinent and will return a special error if the desired command is not supported for the selected specification.
Quoted 4 lines
Thanks for doing all of this. Can you please enable this feature on sandbox and/or an x86 QEMU variant where I assume we could also then setup automated testing?
Not sure I understand your request correctly: the TPM commands are already available in the sandbox (I don't see what I could add), I just extended the current set of commands.
Quoted 5 lines
However, even with these commands, we won't be able to test them in a sandbox unless with an actual device.
I probably miss something, can you explain a bit more what you would like?
Can we add a valid TPM via QEMU and then test it that way? If so, we should enable the TPM code on qemu-x86_64 (and, well, if we can pass it on other arches, other QEMU targets) and write some test/py/tests/ code that exercises the TPM commands. Does that make sense?
Signature · 8 lines
Tom -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: not available URL: <http://lists.denx.de/pipermail/u-boot/attachments/20180309/709ab96d/attachment.sig>
cover Introduce SPI TPM v2.0 support
Hi Tom,
Sorry for the delay.
Quoted 33 lines · Tom Rini
Quoted 32 lines · Miquel Raynal
Hi Tom,
Quoted 16 lines · Tom Rini
Quoted 8 lines · Miquel Raynal
Current U-Boot supports TPM v1.2 specification. The new specification (v2.0) is not backward compatible and renames/introduces several functions.
This series introduces a new SPI driver following the TPM v2.0 specification. It has been tested on a ST TPM but should be usable with others v2.0 compliant chips.
Quoted 5 lines
Then, basic functionalities are introduced one by one for the v2.0 specification. The INIT command now can receive a parameter to distinguish further TPMv1/TPMv2 commands. After that, the library itself will know which one is pertinent and will return a special error if the desired command is not supported for the selected specification.
Quoted 4 lines
Thanks for doing all of this. Can you please enable this feature on sandbox and/or an x86 QEMU variant where I assume we could also then setup automated testing?
Not sure I understand your request correctly: the TPM commands are already available in the sandbox (I don't see what I could add), I just extended the current set of commands.
However, even with these commands, we won't be able to test them in a sandbox unless with an actual device.
Quoted 8 lines
Quoted 2 lines
I probably miss something, can you explain a bit more what you would like?
Can we add a valid TPM via QEMU and then test it that way? If so, we should enable the TPM code on qemu-x86_64 (and, well, if we can pass it on other arches, other QEMU targets) and write some test/py/tests/ code that exercises the TPM commands. Does that make sense?
I suppose this is doable, but for what I know, the effort is consequent. TPM 2.0 are not compatible at all with TPM 1.x , the packets exchanged at TPM level are completely different. Hence, I think there is almost nothing that we can take from the TPM 1.x implementation already existing in QEMU.
I am certain we all would benefit such a contribution, however I'm not sure I could handle that anytime soon.
About the series, I think it would be better that I change a macro name ("STRINGIFY", which is wrongly named), I will send a v2 soon, can you tell me its status otherwise?
Thank you,
Miquèl
Signature · 3 lines
Miquel Raynal, Bootlin (formerly Free Electrons) Embedded Linux and Kernel engineering https://bootlin.com
cover Introduce SPI TPM v2.0 support
Quoted 48 lines · Miquel Raynal
Hi Tom,
Sorry for the delay.
Quoted 33 lines · Tom Rini
Quoted 32 lines · Miquel Raynal
Hi Tom,
Quoted 16 lines · Tom Rini
Quoted 8 lines · Miquel Raynal
Current U-Boot supports TPM v1.2 specification. The new specification (v2.0) is not backward compatible and renames/introduces several functions.
This series introduces a new SPI driver following the TPM v2.0 specification. It has been tested on a ST TPM but should be usable with others v2.0 compliant chips.
Quoted 5 lines
Then, basic functionalities are introduced one by one for the v2.0 specification. The INIT command now can receive a parameter to distinguish further TPMv1/TPMv2 commands. After that, the library itself will know which one is pertinent and will return a special error if the desired command is not supported for the selected specification.
Quoted 4 lines
Thanks for doing all of this. Can you please enable this feature on sandbox and/or an x86 QEMU variant where I assume we could also then setup automated testing?
Not sure I understand your request correctly: the TPM commands are already available in the sandbox (I don't see what I could add), I just extended the current set of commands.
However, even with these commands, we won't be able to test them in a sandbox unless with an actual device.
Quoted 8 lines
Quoted 2 lines
I probably miss something, can you explain a bit more what you would like?
Can we add a valid TPM via QEMU and then test it that way? If so, we should enable the TPM code on qemu-x86_64 (and, well, if we can pass it on other arches, other QEMU targets) and write some test/py/tests/ code that exercises the TPM commands. Does that make sense?
Quoted 5 lines
I suppose this is doable, but for what I know, the effort is consequent. TPM 2.0 are not compatible at all with TPM 1.x , the packets exchanged at TPM level are completely different. Hence, I think there is almost nothing that we can take from the TPM 1.x implementation already existing in QEMU.
Ah, OK. I thought QEMU had a TPM 2.0 implementation now too, but I see I'm mistaken.
Quoted 6 lines
I am certain we all would benefit such a contribution, however I'm not sure I could handle that anytime soon.
About the series, I think it would be better that I change a macro name ("STRINGIFY", which is wrongly named), I will send a v2 soon, can you tell me its status otherwise?
We have the usual linux/stringify.h header available, so yes, you should make use of that. And I still would like to see tests written, even if they can only be executed on $board with $TPM attached via $interface, with those 3 variables documented so that others can try it out too. Does that make sense? Thanks!
Signature · 8 lines
Tom -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: not available URL: <http://lists.denx.de/pipermail/u-boot/attachments/20180320/0bbb50f6/attachment.sig>
cover Introduce SPI TPM v2.0 support
Hi Tom,
Quoted 61 lines · Tom Rini
Quoted 48 lines · Miquel Raynal
Hi Tom,
Sorry for the delay.
Quoted 33 lines · Tom Rini
Quoted 32 lines · Miquel Raynal
Hi Tom,
Quoted 16 lines · Tom Rini
Quoted 8 lines · Miquel Raynal
Current U-Boot supports TPM v1.2 specification. The new specification (v2.0) is not backward compatible and renames/introduces several functions.
This series introduces a new SPI driver following the TPM v2.0 specification. It has been tested on a ST TPM but should be usable with others v2.0 compliant chips.
Quoted 5 lines
Then, basic functionalities are introduced one by one for the v2.0 specification. The INIT command now can receive a parameter to distinguish further TPMv1/TPMv2 commands. After that, the library itself will know which one is pertinent and will return a special error if the desired command is not supported for the selected specification.
Quoted 4 lines
Thanks for doing all of this. Can you please enable this feature on sandbox and/or an x86 QEMU variant where I assume we could also then setup automated testing?
Not sure I understand your request correctly: the TPM commands are already available in the sandbox (I don't see what I could add), I just extended the current set of commands.
However, even with these commands, we won't be able to test them in a sandbox unless with an actual device.
Quoted 8 lines
Quoted 2 lines
I probably miss something, can you explain a bit more what you would like?
Can we add a valid TPM via QEMU and then test it that way? If so, we should enable the TPM code on qemu-x86_64 (and, well, if we can pass it on other arches, other QEMU targets) and write some test/py/tests/ code that exercises the TPM commands. Does that make sense?
Quoted 5 lines
I suppose this is doable, but for what I know, the effort is consequent. TPM 2.0 are not compatible at all with TPM 1.x , the packets exchanged at TPM level are completely different. Hence, I think there is almost nothing that we can take from the TPM 1.x implementation already existing in QEMU.
Ah, OK. I thought QEMU had a TPM 2.0 implementation now too, but I see I'm mistaken.
Quoted 3 lines
I am certain we all would benefit such a contribution, however I'm not sure I could handle that anytime soon.
Quoted 6 lines
Quoted 3 lines
About the series, I think it would be better that I change a macro name ("STRINGIFY", which is wrongly named), I will send a v2 soon, can you tell me its status otherwise?
We have the usual
linux/stringify.hheader available, so yes, you should make use of that.
Actually the name is misleading as I don't want to "stringify".
I am looking for a way to easily fill a buffer of bytes from integer values, ie:
u32 value = 0x12345678;
u8 buf[x] = { MACRO(value), ...} to be {0x12, 0x34, 0x56, 0x78, ...}
Quoted 4 lines
And I still would like to see tests written, even if
they can only be executed on $board with $TPM attached via $interface, with those 3 variables documented so that others can try it out too. Does that make sense? Thanks!
I see some TPM tests for v1.x, I can probably add some there. This will test the library functions but not the "user" commands.
To test the commands, I suggest following the lines I inserted in my cover letter, but maybe I can put it also in some documentation?
Would this fit your expectations?
[1] https://lists.denx.de/pipermail/u-boot/2018-March/322286.html
Thanks,
Miquèl
Signature · 3 lines
Miquel Raynal, Bootlin (formerly Free Electrons) Embedded Linux and Kernel engineering https://bootlin.com
cover Introduce SPI TPM v2.0 support
Quoted 86 lines · Miquel Raynal
Hi Tom,
Quoted 61 lines · Tom Rini
Quoted 48 lines · Miquel Raynal
Hi Tom,
Sorry for the delay.
Quoted 33 lines · Tom Rini
Quoted 32 lines · Miquel Raynal
Hi Tom,
Quoted 16 lines · Tom Rini
Quoted 8 lines · Miquel Raynal
Current U-Boot supports TPM v1.2 specification. The new specification (v2.0) is not backward compatible and renames/introduces several functions.
This series introduces a new SPI driver following the TPM v2.0 specification. It has been tested on a ST TPM but should be usable with others v2.0 compliant chips.
Quoted 5 lines
Then, basic functionalities are introduced one by one for the v2.0 specification. The INIT command now can receive a parameter to distinguish further TPMv1/TPMv2 commands. After that, the library itself will know which one is pertinent and will return a special error if the desired command is not supported for the selected specification.
Quoted 4 lines
Thanks for doing all of this. Can you please enable this feature on sandbox and/or an x86 QEMU variant where I assume we could also then setup automated testing?
Not sure I understand your request correctly: the TPM commands are already available in the sandbox (I don't see what I could add), I just extended the current set of commands.
However, even with these commands, we won't be able to test them in a sandbox unless with an actual device.
Quoted 8 lines
Quoted 2 lines
I probably miss something, can you explain a bit more what you would like?
Can we add a valid TPM via QEMU and then test it that way? If so, we should enable the TPM code on qemu-x86_64 (and, well, if we can pass it on other arches, other QEMU targets) and write some test/py/tests/ code that exercises the TPM commands. Does that make sense?
Quoted 5 lines
I suppose this is doable, but for what I know, the effort is consequent. TPM 2.0 are not compatible at all with TPM 1.x , the packets exchanged at TPM level are completely different. Hence, I think there is almost nothing that we can take from the TPM 1.x implementation already existing in QEMU.
Ah, OK. I thought QEMU had a TPM 2.0 implementation now too, but I see I'm mistaken.
Quoted 3 lines
I am certain we all would benefit such a contribution, however I'm not sure I could handle that anytime soon.
Quoted 6 lines
Quoted 3 lines
About the series, I think it would be better that I change a macro name ("STRINGIFY", which is wrongly named), I will send a v2 soon, can you tell me its status otherwise?
We have the usual
linux/stringify.hheader available, so yes, you should make use of that.Actually the name is misleading as I don't want to "stringify".
I am looking for a way to easily fill a buffer of bytes from integer values, ie:
u32 value =
0x12345678;
u8 buf[x] = { MACRO(value), ...} to be {0x12,0x34,0x56,0x78, ...}Quoted 4 lines
And I still would like to see tests written, even if
they can only be executed on $board with $TPM attached via $interface, with those 3 variables documented so that others can try it out too. Does that make sense? Thanks!
Quoted 7 lines
I see some TPM tests for v1.x, I can probably add some there. This will test the library functions but not the "user" commands.
To test the commands, I suggest following the lines I inserted in my cover letter, but maybe I can put it also in some documentation?
Would this fit your expectations?
We have a framework to run those commands on the target and confirm that they behave as expected. Please write the tests to run those commands and confirm that they work as expected. Thanks!
Signature · 8 lines
Tom -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: not available URL: <http://lists.denx.de/pipermail/u-boot/attachments/20180321/2c8f507a/attachment.sig>
cover Introduce SPI TPM v2.0 support
Hi Miquel,
Quoted 90 lines · Tom Rini
Quoted 89 lines · Miquel Raynal
Hi Tom,
Quoted 61 lines · Tom Rini
Quoted 48 lines · Miquel Raynal
Hi Tom,
Sorry for the delay.
Quoted 33 lines · Tom Rini
Quoted 32 lines · Miquel Raynal
Hi Tom,
Quoted 16 lines · Tom Rini
Quoted 8 lines · Miquel Raynal
Current U-Boot supports TPM v1.2 specification. The new specification (v2.0) is not backward compatible and renames/introduces several functions.
This series introduces a new SPI driver following the TPM v2.0 specification. It has been tested on a ST TPM but should be usable with others v2.0 compliant chips.
Quoted 5 lines
Then, basic functionalities are introduced one by one for the v2.0 specification. The INIT command now can receive a parameter to distinguish further TPMv1/TPMv2 commands. After that, the library itself will know which one is pertinent and will return a special error if the desired command is not supported for the selected specification.
Quoted 4 lines
Thanks for doing all of this. Can you please enable this feature on sandbox and/or an x86 QEMU variant where I assume we could also then setup automated testing?
Not sure I understand your request correctly: the TPM commands are already available in the sandbox (I don't see what I could add), I just extended the current set of commands.
However, even with these commands, we won't be able to test them in a sandbox unless with an actual device.
Quoted 8 lines
Quoted 2 lines
I probably miss something, can you explain a bit more what you would like?
Can we add a valid TPM via QEMU and then test it that way? If so, we should enable the TPM code on qemu-x86_64 (and, well, if we can pass it on other arches, other QEMU targets) and write some test/py/tests/ code that exercises the TPM commands. Does that make sense?
Quoted 5 lines
I suppose this is doable, but for what I know, the effort is consequent. TPM 2.0 are not compatible at all with TPM 1.x , the packets exchanged at TPM level are completely different. Hence, I think there is almost nothing that we can take from the TPM 1.x implementation already existing in QEMU.
Ah, OK. I thought QEMU had a TPM 2.0 implementation now too, but I see I'm mistaken.
Quoted 3 lines
I am certain we all would benefit such a contribution, however I'm not sure I could handle that anytime soon.
Quoted 6 lines
Quoted 3 lines
About the series, I think it would be better that I change a macro name ("STRINGIFY", which is wrongly named), I will send a v2 soon, can you tell me its status otherwise?
We have the usual
linux/stringify.hheader available, so yes, you should make use of that.Actually the name is misleading as I don't want to "stringify".
I am looking for a way to easily fill a buffer of bytes from integer values, ie:
u32 value =
0x12345678;
u8 buf[x] = { MACRO(value), ...} to be {0x12,0x34,0x56,0x78, ...}Quoted 4 lines
And I still would like to see tests written, even if
they can only be executed on $board with $TPM attached via $interface, with those 3 variables documented so that others can try it out too. Does that make sense? Thanks!I see some TPM tests for v1.x, I can probably add some there. This will test the library functions but not the "user" commands.
Quoted 8 lines
Quoted 4 lines
To test the commands, I suggest following the lines I inserted in my cover letter, but maybe I can put it also in some documentation?
Would this fit your expectations?
We have a framework to run those commands on the target and confirm that they behave as expected. Please write the tests to run those commands and confirm that they work as expected. Thanks!
Re sandbox, it has a TPM emulator used for testing in tpm_tis_sandbox.c - you should be able to add something similar for v2.
Regards,
Simon
cover Introduce SPI TPM v2.0 support
Hi Simon and Tom,
Quoted 98 lines · Simon Glass
Hi Miquel,
Quoted 95 lines · Tom Rini
Quoted 93 lines · Miquel Raynal
Hi Tom,
Quoted 61 lines · Tom Rini
Quoted 48 lines · Miquel Raynal
Hi Tom,
Sorry for the delay.
Quoted 33 lines · Tom Rini
Quoted 32 lines · Miquel Raynal
Hi Tom,
Quoted 16 lines · Tom Rini
Quoted 8 lines · Miquel Raynal
Current U-Boot supports TPM v1.2 specification. The new specification (v2.0) is not backward compatible and renames/introduces several functions.
This series introduces a new SPI driver following the TPM v2.0 specification. It has been tested on a ST TPM but should be usable with others v2.0 compliant chips.
Quoted 5 lines
Then, basic functionalities are introduced one by one for the v2.0 specification. The INIT command now can receive a parameter to distinguish further TPMv1/TPMv2 commands. After that, the library itself will know which one is pertinent and will return a special error if the desired command is not supported for the selected specification.
Quoted 4 lines
Thanks for doing all of this. Can you please enable this feature on sandbox and/or an x86 QEMU variant where I assume we could also then setup automated testing?
Not sure I understand your request correctly: the TPM commands are already available in the sandbox (I don't see what I could add), I just extended the current set of commands.
However, even with these commands, we won't be able to test them in a sandbox unless with an actual device.
Quoted 8 lines
Quoted 2 lines
I probably miss something, can you explain a bit more what you would like?
Can we add a valid TPM via QEMU and then test it that way? If so, we should enable the TPM code on qemu-x86_64 (and, well, if we can pass it on other arches, other QEMU targets) and write some test/py/tests/ code that exercises the TPM commands. Does that make sense?
Quoted 5 lines
I suppose this is doable, but for what I know, the effort is consequent. TPM 2.0 are not compatible at all with TPM 1.x , the packets exchanged at TPM level are completely different. Hence, I think there is almost nothing that we can take from the TPM 1.x implementation already existing in QEMU.
Ah, OK. I thought QEMU had a TPM 2.0 implementation now too, but I see I'm mistaken.
Quoted 3 lines
I am certain we all would benefit such a contribution, however I'm not sure I could handle that anytime soon.
Quoted 6 lines
Quoted 3 lines
About the series, I think it would be better that I change a macro name ("STRINGIFY", which is wrongly named), I will send a v2 soon, can you tell me its status otherwise?
We have the usual
linux/stringify.hheader available, so yes, you should make use of that.Actually the name is misleading as I don't want to "stringify".
I am looking for a way to easily fill a buffer of bytes from integer values, ie:
u32 value =
0x12345678;
u8 buf[x] = { MACRO(value), ...} to be {0x12,0x34,0x56,0x78, ...}Quoted 4 lines
And I still would like to see tests written, even if
they can only be executed on $board with $TPM attached via $interface, with those 3 variables documented so that others can try it out too. Does that make sense? Thanks!I see some TPM tests for v1.x, I can probably add some there. This will test the library functions but not the "user" commands.
To test the commands, I suggest following the lines I inserted in my cover letter, but maybe I can put it also in some documentation?
Would this fit your expectations?
Quoted 7 lines
Quoted 3 lines
We have a framework to run those commands on the target and confirm that they behave as expected. Please write the tests to run those commands and confirm that they work as expected. Thanks!
Re sandbox, it has a TPM emulator used for testing in
tpm_tis_sandbox.c- you should be able to add something similar for v2.
I wrote a complete test suite for all the TPMv2.0 commands. It runs completely fine with real hardware, see the last patch of the v2 series. I had a look to sandbox but I'm sorry, I really don't have enough time for now to achieve this additional work, I really hope the full Python test suite will be enough.
Regards,
Miquèl
Signature · 3 lines
Miquel Raynal, Bootlin (formerly Free Electrons) Embedded Linux and Kernel engineering https://bootlin.com
cover Introduce SPI TPM v2.0 support
Hi Miquel,
Quoted 111 lines · Miquel Raynal
Hi Simon and Tom,
Quoted 98 lines · Simon Glass
Hi Miquel,
Quoted 95 lines · Tom Rini
Quoted 93 lines · Miquel Raynal
Hi Tom,
Quoted 61 lines · Tom Rini
Quoted 48 lines · Miquel Raynal
Hi Tom,
Sorry for the delay.
Quoted 33 lines · Tom Rini
Quoted 32 lines · Miquel Raynal
Hi Tom,
Quoted 16 lines · Tom Rini
Quoted 8 lines · Miquel Raynal
Current U-Boot supports TPM v1.2 specification. The new specification (v2.0) is not backward compatible and renames/introduces several functions.
This series introduces a new SPI driver following the TPM v2.0 specification. It has been tested on a ST TPM but should be usable with others v2.0 compliant chips.
Quoted 5 lines
Then, basic functionalities are introduced one by one for the v2.0 specification. The INIT command now can receive a parameter to distinguish further TPMv1/TPMv2 commands. After that, the library itself will know which one is pertinent and will return a special error if the desired command is not supported for the selected specification.
Quoted 4 lines
Thanks for doing all of this. Can you please enable this feature on sandbox and/or an x86 QEMU variant where I assume we could also then setup automated testing?
Not sure I understand your request correctly: the TPM commands are already available in the sandbox (I don't see what I could add), I just extended the current set of commands.
However, even with these commands, we won't be able to test them in a sandbox unless with an actual device.
Quoted 8 lines
Quoted 2 lines
I probably miss something, can you explain a bit more what you would like?
Can we add a valid TPM via QEMU and then test it that way? If so, we should enable the TPM code on qemu-x86_64 (and, well, if we can pass it on other arches, other QEMU targets) and write some test/py/tests/ code that exercises the TPM commands. Does that make sense?
Quoted 5 lines
I suppose this is doable, but for what I know, the effort is consequent. TPM 2.0 are not compatible at all with TPM 1.x , the packets exchanged at TPM level are completely different. Hence, I think there is almost nothing that we can take from the TPM 1.x implementation already existing in QEMU.
Ah, OK. I thought QEMU had a TPM 2.0 implementation now too, but I see I'm mistaken.
Quoted 3 lines
I am certain we all would benefit such a contribution, however I'm not sure I could handle that anytime soon.
Quoted 6 lines
Quoted 3 lines
About the series, I think it would be better that I change a macro name ("STRINGIFY", which is wrongly named), I will send a v2 soon, can you tell me its status otherwise?
We have the usual
linux/stringify.hheader available, so yes, you should make use of that.Actually the name is misleading as I don't want to "stringify".
I am looking for a way to easily fill a buffer of bytes from integer values, ie:
u32 value =
0x12345678;
u8 buf[x] = { MACRO(value), ...} to be {0x12,0x34,0x56,0x78, ...}Quoted 4 lines
And I still would like to see tests written, even if
they can only be executed on $board with $TPM attached via $interface, with those 3 variables documented so that others can try it out too. Does that make sense? Thanks!I see some TPM tests for v1.x, I can probably add some there. This will test the library functions but not the "user" commands.
To test the commands, I suggest following the lines I inserted in my cover letter, but maybe I can put it also in some documentation?
Would this fit your expectations?
Quoted 7 lines
Quoted 3 lines
We have a framework to run those commands on the target and confirm that they behave as expected. Please write the tests to run those commands and confirm that they work as expected. Thanks!
Re sandbox, it has a TPM emulator used for testing in
tpm_tis_sandbox.c- you should be able to add something similar for v2.
Quoted 5 lines
I wrote a complete test suite for all the TPMv2.0 commands. It runs completely fine with real hardware, see the last patch of the v2 series. I had a look to sandbox but I'm sorry, I really don't have enough time for now to achieve this additional work, I really hope the full Python test suite will be enough.
This should not take very long to do. I am not keen to add this new support without sandbox tests. The Python test suite is a great idea, but running it on real hardware is not an option for most people.
Lots of people have made big efforts to improve the sandbox testing in U-Boot. We need to keep pushing it forward, not regressing.
Regards,
Simon