diff options
author | Miquel Raynal <miquel.raynal@bootlin.com> | 2018-05-15 11:57:19 +0200 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2018-05-25 20:12:58 -0400 |
commit | dc26e913a8d1a62bd4112f41232e0273ee66423d (patch) | |
tree | 6f4bb41b953a1df5d245b2a4205fa6eb3234abd6 | |
parent | da9c3392e6cb2f3bf6d9973b1bda3b6881608b8e (diff) | |
download | u-boot-dc26e913a8d1a62bd4112f41232e0273ee66423d.zip u-boot-dc26e913a8d1a62bd4112f41232e0273ee66423d.tar.gz u-boot-dc26e913a8d1a62bd4112f41232e0273ee66423d.tar.bz2 |
tpm: add TPM2_HierarchyChangeAuth command support
Add support for the TPM2_HierarchyChangeAuth command.
Change the command file and the help accordingly.
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Tom Rini <trini@konsulko.com>
-rw-r--r-- | cmd/tpm-v2.c | 59 | ||||
-rw-r--r-- | include/tpm-v2.h | 14 | ||||
-rw-r--r-- | lib/tpm-v2.c | 44 |
3 files changed, 105 insertions, 12 deletions
diff --git a/cmd/tpm-v2.c b/cmd/tpm-v2.c index 4a5b40b..c245440 100644 --- a/cmd/tpm-v2.c +++ b/cmd/tpm-v2.c @@ -234,6 +234,36 @@ static int do_tpm_dam_parameters(cmd_tbl_t *cmdtp, int flag, int argc, lockout_recovery)); } +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_LEN || oldpw_sz > TPM2_DIGEST_LEN) + 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)); +} + static cmd_tbl_t tpm2_commands[] = { U_BOOT_CMD_MKENT(info, 0, 1, do_tpm_info, "", ""), U_BOOT_CMD_MKENT(init, 0, 1, do_tpm_init, "", ""), @@ -245,6 +275,7 @@ static cmd_tbl_t tpm2_commands[] = { U_BOOT_CMD_MKENT(get_capability, 0, 1, do_tpm_get_capability, "", ""), U_BOOT_CMD_MKENT(dam_reset, 0, 1, do_tpm_dam_reset, "", ""), U_BOOT_CMD_MKENT(dam_parameters, 0, 1, do_tpm_dam_parameters, "", ""), + U_BOOT_CMD_MKENT(change_auth, 0, 1, do_tpm_change_auth, "", ""), }; cmd_tbl_t *get_tpm_commands(unsigned int *size) @@ -291,16 +322,20 @@ U_BOOT_CMD(tpm, CONFIG_SYS_MAXARGS, 1, do_tpm, "Issue a TPMv2.x command", " <property>: property\n" " <addr>: address to store <count> entries of 4 bytes\n" " <count>: number of entries to retrieve\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" +"dam_reset [<password>]\n" +" If the TPM is not in a LOCKOUT state, reset the internal error counter.\n" +" <password>: optional password\n" +"dam_parameters <max_tries> <recovery_time> <lockout_recovery> [<password>]\n" +" If the TPM is not in a LOCKOUT state, set the DAM parameters\n" +" <maxTries>: maximum number of failures before lockout,\n" +" 0 means always locking\n" +" <recoveryTime>: time before decrement 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" +" <password>: optional password of the LOCKOUT hierarchy\n" +"change_auth <hierarchy> <new_pw> [<old_pw>]\n" +" <hierarchy>: the hierarchy\n" +" <new_pw>: new password for <hierarchy>\n" +" <old_pw>: optional previous password of <hierarchy>\n" ); diff --git a/include/tpm-v2.h b/include/tpm-v2.h index ab8f113..be1aa2c 100644 --- a/include/tpm-v2.h +++ b/include/tpm-v2.h @@ -216,4 +216,18 @@ u32 tpm2_dam_parameters(const char *pw, const ssize_t pw_sz, unsigned int max_tries, unsigned int recovery_time, unsigned int lockout_recovery); +/** + * Issue a TPM2_HierarchyChangeAuth command. + * + * @handle Handle + * @newpw New password + * @newpw_sz Length of the new password + * @oldpw Old password + * @oldpw_sz Length of the old password + * + * @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); + #endif /* __TPM_V2_H */ diff --git a/lib/tpm-v2.c b/lib/tpm-v2.c index 9a65e7d..ffe8613 100644 --- a/lib/tpm-v2.c +++ b/lib/tpm-v2.c @@ -273,3 +273,47 @@ u32 tpm2_dam_parameters(const char *pw, const ssize_t pw_sz, return tpm_sendrecv_command(command_v2, NULL, NULL); } + +int tpm2_change_auth(u32 handle, const char *newpw, const ssize_t newpw_sz, + const char *oldpw, const ssize_t oldpw_sz) +{ + unsigned int offset = 27; + u8 command_v2[COMMAND_BUFFER_SIZE] = { + tpm_u16(TPM2_ST_SESSIONS), /* TAG */ + tpm_u32(offset + oldpw_sz + 2 + newpw_sz), /* Length */ + tpm_u32(TPM2_CC_HIERCHANGEAUTH), /* Command code */ + + /* HANDLE */ + tpm_u32(handle), /* TPM resource handle */ + + /* AUTH_SESSION */ + tpm_u32(9 + oldpw_sz), /* Authorization size */ + tpm_u32(TPM2_RS_PW), /* Session handle */ + tpm_u16(0), /* Size of <nonce> */ + /* <nonce> (if any) */ + 0, /* Attributes: Cont/Excl/Rst */ + tpm_u16(oldpw_sz) /* Size of <hmac/password> */ + /* STRING(oldpw) <hmac/password> (if any) */ + + /* TPM2B_AUTH (TPM2B_DIGEST) */ + /* tpm_u16(newpw_sz) Digest size, new pw length */ + /* STRING(newpw) Digest buffer, new pw */ + }; + int ret; + + /* + * Fill the command structure starting from the first buffer: + * - the old password (if any) + * - size of the new password + * - new password + */ + ret = pack_byte_string(command_v2, sizeof(command_v2), "sws", + offset, oldpw, oldpw_sz, + offset + oldpw_sz, newpw_sz, + offset + oldpw_sz + 2, newpw, newpw_sz); + offset += oldpw_sz + 2 + newpw_sz; + if (ret) + return TPM_LIB_ERROR; + + return tpm_sendrecv_command(command_v2, NULL, NULL); +} |