X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=lib%2Ftpm-v2.c;h=f89592d6e2f33166e31b8e5975ac838e1548577f;hb=beeb57f0a66658aacad3f12f1a31e65f5d22e46d;hp=9a65e7de42399a672cbb19e323aceba7a2fb8af1;hpb=da9c3392e6cb2f3bf6d9973b1bda3b6881608b8e;p=oweals%2Fu-boot.git diff --git a/lib/tpm-v2.c b/lib/tpm-v2.c index 9a65e7de42..f89592d6e2 100644 --- a/lib/tpm-v2.c +++ b/lib/tpm-v2.c @@ -10,7 +10,7 @@ #include #include "tpm-utils.h" -u32 tpm2_startup(enum tpm2_startup_types mode) +u32 tpm2_startup(struct udevice *dev, enum tpm2_startup_types mode) { const u8 command_v2[12] = { tpm_u16(TPM2_ST_NO_SESSIONS), @@ -24,14 +24,14 @@ u32 tpm2_startup(enum tpm2_startup_types mode) * Note TPM2_Startup command will return RC_SUCCESS the first time, * but will return RC_INITIALIZE otherwise. */ - ret = tpm_sendrecv_command(command_v2, NULL, NULL); + ret = tpm_sendrecv_command(dev, command_v2, NULL, NULL); if (ret && ret != TPM2_RC_INITIALIZE) return ret; return 0; } -u32 tpm2_self_test(enum tpm2_yes_no full_test) +u32 tpm2_self_test(struct udevice *dev, enum tpm2_yes_no full_test) { const u8 command_v2[12] = { tpm_u16(TPM2_ST_NO_SESSIONS), @@ -40,10 +40,11 @@ u32 tpm2_self_test(enum tpm2_yes_no full_test) full_test, }; - return tpm_sendrecv_command(command_v2, NULL, NULL); + return tpm_sendrecv_command(dev, command_v2, NULL, NULL); } -u32 tpm2_clear(u32 handle, const char *pw, const ssize_t pw_sz) +u32 tpm2_clear(struct udevice *dev, u32 handle, const char *pw, + const ssize_t pw_sz) { u8 command_v2[COMMAND_BUFFER_SIZE] = { tpm_u16(TPM2_ST_SESSIONS), /* TAG */ @@ -75,10 +76,10 @@ u32 tpm2_clear(u32 handle, const char *pw, const ssize_t pw_sz) if (ret) return TPM_LIB_ERROR; - return tpm_sendrecv_command(command_v2, NULL, NULL); + return tpm_sendrecv_command(dev, command_v2, NULL, NULL); } -u32 tpm2_pcr_extend(u32 index, const uint8_t *digest) +u32 tpm2_pcr_extend(struct udevice *dev, u32 index, const uint8_t *digest) { u8 command_v2[COMMAND_BUFFER_SIZE] = { tpm_u16(TPM2_ST_SESSIONS), /* TAG */ @@ -113,11 +114,11 @@ u32 tpm2_pcr_extend(u32 index, const uint8_t *digest) if (ret) return TPM_LIB_ERROR; - return tpm_sendrecv_command(command_v2, NULL, NULL); + return tpm_sendrecv_command(dev, command_v2, NULL, NULL); } -u32 tpm2_pcr_read(u32 idx, unsigned int idx_min_sz, void *data, - unsigned int *updates) +u32 tpm2_pcr_read(struct udevice *dev, u32 idx, unsigned int idx_min_sz, + void *data, unsigned int *updates) { u8 idx_array_sz = max(idx_min_sz, DIV_ROUND_UP(idx, 8)); u8 command_v2[COMMAND_BUFFER_SIZE] = { @@ -142,7 +143,7 @@ u32 tpm2_pcr_read(u32 idx, unsigned int idx_min_sz, void *data, 17 + pcr_sel_idx, pcr_sel_bit)) return TPM_LIB_ERROR; - ret = tpm_sendrecv_command(command_v2, response, &response_len); + ret = tpm_sendrecv_command(dev, command_v2, response, &response_len); if (ret) return ret; @@ -158,8 +159,8 @@ u32 tpm2_pcr_read(u32 idx, unsigned int idx_min_sz, void *data, return 0; } -u32 tpm2_get_capability(u32 capability, u32 property, void *buf, - size_t prop_count) +u32 tpm2_get_capability(struct udevice *dev, u32 capability, u32 property, + void *buf, size_t prop_count) { u8 command_v2[COMMAND_BUFFER_SIZE] = { tpm_u16(TPM2_ST_NO_SESSIONS), /* TAG */ @@ -175,7 +176,7 @@ u32 tpm2_get_capability(u32 capability, u32 property, void *buf, unsigned int properties_off; int ret; - ret = tpm_sendrecv_command(command_v2, response, &response_len); + ret = tpm_sendrecv_command(dev, command_v2, response, &response_len); if (ret) return ret; @@ -191,7 +192,7 @@ u32 tpm2_get_capability(u32 capability, u32 property, void *buf, return 0; } -u32 tpm2_dam_reset(const char *pw, const ssize_t pw_sz) +u32 tpm2_dam_reset(struct udevice *dev, const char *pw, const ssize_t pw_sz) { u8 command_v2[COMMAND_BUFFER_SIZE] = { tpm_u16(TPM2_ST_SESSIONS), /* TAG */ @@ -223,11 +224,12 @@ u32 tpm2_dam_reset(const char *pw, const ssize_t pw_sz) if (ret) return TPM_LIB_ERROR; - return tpm_sendrecv_command(command_v2, NULL, NULL); + return tpm_sendrecv_command(dev, command_v2, NULL, NULL); } -u32 tpm2_dam_parameters(const char *pw, const ssize_t pw_sz, - unsigned int max_tries, unsigned int recovery_time, +u32 tpm2_dam_parameters(struct udevice *dev, const char *pw, + const ssize_t pw_sz, unsigned int max_tries, + unsigned int recovery_time, unsigned int lockout_recovery) { u8 command_v2[COMMAND_BUFFER_SIZE] = { @@ -271,5 +273,151 @@ u32 tpm2_dam_parameters(const char *pw, const ssize_t pw_sz, if (ret) return TPM_LIB_ERROR; - return tpm_sendrecv_command(command_v2, NULL, NULL); + return tpm_sendrecv_command(dev, command_v2, NULL, NULL); +} + +int tpm2_change_auth(struct udevice *dev, 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 */ + /* (if any) */ + 0, /* Attributes: Cont/Excl/Rst */ + tpm_u16(oldpw_sz) /* Size of */ + /* STRING(oldpw) (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(dev, command_v2, NULL, NULL); +} + +u32 tpm2_pcr_setauthpolicy(struct udevice *dev, const char *pw, + const ssize_t pw_sz, u32 index, const char *key) +{ + u8 command_v2[COMMAND_BUFFER_SIZE] = { + tpm_u16(TPM2_ST_SESSIONS), /* TAG */ + tpm_u32(35 + pw_sz + TPM2_DIGEST_LEN), /* Length */ + tpm_u32(TPM2_CC_PCR_SETAUTHPOL), /* Command code */ + + /* HANDLE */ + tpm_u32(TPM2_RH_PLATFORM), /* TPM resource handle */ + + /* AUTH_SESSION */ + tpm_u32(9 + pw_sz), /* Authorization size */ + tpm_u32(TPM2_RS_PW), /* session handle */ + tpm_u16(0), /* Size of */ + /* (if any) */ + 0, /* Attributes: Cont/Excl/Rst */ + tpm_u16(pw_sz) /* Size of */ + /* STRING(pw) (if any) */ + + /* TPM2B_AUTH (TPM2B_DIGEST) */ + /* tpm_u16(TPM2_DIGEST_LEN) Digest size length */ + /* STRING(key) Digest buffer (PCR key) */ + + /* TPMI_ALG_HASH */ + /* tpm_u16(TPM2_ALG_SHA256) Algorithm of the hash */ + + /* TPMI_DH_PCR */ + /* tpm_u32(index), PCR Index */ + }; + unsigned int offset = 27; + int ret; + + /* + * Fill the command structure starting from the first buffer: + * - the password (if any) + * - the PCR key length + * - the PCR key + * - the hash algorithm + * - the PCR index + */ + ret = pack_byte_string(command_v2, sizeof(command_v2), "swswd", + offset, pw, pw_sz, + offset + pw_sz, TPM2_DIGEST_LEN, + offset + pw_sz + 2, key, TPM2_DIGEST_LEN, + offset + pw_sz + 2 + TPM2_DIGEST_LEN, + TPM2_ALG_SHA256, + offset + pw_sz + 4 + TPM2_DIGEST_LEN, index); + offset += pw_sz + 2 + TPM2_DIGEST_LEN + 2 + 4; + if (ret) + return TPM_LIB_ERROR; + + return tpm_sendrecv_command(dev, command_v2, NULL, NULL); +} + +u32 tpm2_pcr_setauthvalue(struct udevice *dev, const char *pw, + const ssize_t pw_sz, u32 index, const char *key, + const ssize_t key_sz) +{ + u8 command_v2[COMMAND_BUFFER_SIZE] = { + tpm_u16(TPM2_ST_SESSIONS), /* TAG */ + tpm_u32(33 + pw_sz + TPM2_DIGEST_LEN), /* Length */ + tpm_u32(TPM2_CC_PCR_SETAUTHVAL), /* Command code */ + + /* HANDLE */ + tpm_u32(index), /* Handle (PCR Index) */ + + /* AUTH_SESSION */ + tpm_u32(9 + pw_sz), /* Authorization size */ + tpm_u32(TPM2_RS_PW), /* session handle */ + tpm_u16(0), /* Size of */ + /* (if any) */ + 0, /* Attributes: Cont/Excl/Rst */ + tpm_u16(pw_sz), /* Size of */ + /* STRING(pw) (if any) */ + + /* TPM2B_DIGEST */ + /* tpm_u16(key_sz) Key length */ + /* STRING(key) Key */ + }; + unsigned int offset = 27; + int ret; + + /* + * Fill the command structure starting from the first buffer: + * - the password (if any) + * - the number of digests, 1 in our case + * - the algorithm, sha256 in our case + * - the digest (64 bytes) + */ + ret = pack_byte_string(command_v2, sizeof(command_v2), "sws", + offset, pw, pw_sz, + offset + pw_sz, key_sz, + offset + pw_sz + 2, key, key_sz); + offset += pw_sz + 2 + key_sz; + if (ret) + return TPM_LIB_ERROR; + + return tpm_sendrecv_command(dev, command_v2, NULL, NULL); }