return 0;
}
+
+u32 tpm2_dam_reset(const char *pw, const ssize_t pw_sz)
+{
+ u8 command_v2[COMMAND_BUFFER_SIZE] = {
+ tpm_u16(TPM2_ST_SESSIONS), /* TAG */
+ tpm_u32(27 + pw_sz), /* Length */
+ tpm_u32(TPM2_CC_DAM_RESET), /* Command code */
+
+ /* HANDLE */
+ tpm_u32(TPM2_RH_LOCKOUT), /* TPM resource handle */
+
+ /* AUTH_SESSION */
+ tpm_u32(9 + pw_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(pw_sz), /* Size of <hmac/password> */
+ /* STRING(pw) <hmac/password> (if any) */
+ };
+ unsigned int offset = 27;
+ int ret;
+
+ /*
+ * Fill the command structure starting from the first buffer:
+ * - the password (if any)
+ */
+ ret = pack_byte_string(command_v2, sizeof(command_v2), "s",
+ offset, pw, pw_sz);
+ offset += pw_sz;
+ if (ret)
+ return TPM_LIB_ERROR;
+
+ return tpm_sendrecv_command(command_v2, NULL, NULL);
+}
+
+u32 tpm2_dam_parameters(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] = {
+ tpm_u16(TPM2_ST_SESSIONS), /* TAG */
+ tpm_u32(27 + pw_sz + 12), /* Length */
+ tpm_u32(TPM2_CC_DAM_PARAMETERS), /* Command code */
+
+ /* HANDLE */
+ tpm_u32(TPM2_RH_LOCKOUT), /* TPM resource handle */
+
+ /* AUTH_SESSION */
+ tpm_u32(9 + pw_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(pw_sz), /* Size of <hmac/password> */
+ /* STRING(pw) <hmac/password> (if any) */
+
+ /* LOCKOUT PARAMETERS */
+ /* tpm_u32(max_tries) Max tries (0, always lock) */
+ /* tpm_u32(recovery_time) Recovery time (0, no lock) */
+ /* tpm_u32(lockout_recovery) Lockout recovery */
+ };
+ unsigned int offset = 27;
+ int ret;
+
+ /*
+ * Fill the command structure starting from the first buffer:
+ * - the password (if any)
+ * - max tries
+ * - recovery time
+ * - lockout recovery
+ */
+ ret = pack_byte_string(command_v2, sizeof(command_v2), "sddd",
+ offset, pw, pw_sz,
+ offset + pw_sz, max_tries,
+ offset + pw_sz + 4, recovery_time,
+ offset + pw_sz + 8, lockout_recovery);
+ offset += pw_sz + 12;
+ if (ret)
+ return TPM_LIB_ERROR;
+
+ 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);
+}
+
+u32 tpm2_pcr_setauthpolicy(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 <nonce> */
+ /* <nonce> (if any) */
+ 0, /* Attributes: Cont/Excl/Rst */
+ tpm_u16(pw_sz) /* Size of <hmac/password> */
+ /* STRING(pw) <hmac/password> (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(command_v2, NULL, NULL);
+}
+
+u32 tpm2_pcr_setauthvalue(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 <nonce> */
+ /* <nonce> (if any) */
+ 0, /* Attributes: Cont/Excl/Rst */
+ tpm_u16(pw_sz), /* Size of <hmac/password> */
+ /* STRING(pw) <hmac/password> (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(command_v2, NULL, NULL);
+}