Re: [PATCH v7 15/21] tpm: Add the rest of the session HMAC API

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue Feb 13, 2024 at 7:13 PM EET, James Bottomley wrote:
> The final pieces of the HMAC API are for manipulating the session area
> of the command.  To add an authentication HMAC session
> tpm_buf_append_hmac_session() is called where tpm2_append_auth() would
> go. If a non empty password is passed in, this is correctly added to
> the HMAC to prove knowledge of it without revealing it.  Note that if
> the session is only used to encrypt or decrypt parameters (no
> authentication) then tpm_buf_append_hmac_session_opt() must be used
> instead.  This functions identically to tpm_buf_append_hmac_session()
> when TPM_BUS_SECURITY is enabled, but differently when it isn't,
> because effectively nothing is appended to the session area.
>
> Next the parameters should be filled in for the command and finally
> tpm_buf_fill_hmac_session() is called immediatly prior to transmitting
> the command which computes the correct HMAC and places it in the
> command at the session location in the tpm buffer
>
> Finally, after tpm_transmit_cmd() is called,
> tpm_buf_check_hmac_response() is called to check that the returned
> HMAC matched and collect the new state for the next use of the
> session, if any.
>
> The features of the session are controlled by the session attributes
> set in tpm_buf_append_hmac_session().  If TPM2_SA_CONTINUE_SESSION is
> not specified, the session will be flushed and the tpm2_auth structure
> freed in tpm_buf_check_hmac_response(); otherwise the session may be
> used again.  Parameter encryption is specified by or'ing the flag
> TPM2_SA_DECRYPT and response encryption by or'ing the flag
> TPM2_SA_ENCRYPT.  the various encryptions will be taken care of by
> tpm_buf_fill_hmac_session() and tpm_buf_check_hmac_response()
> respectively.
>
> Signed-off-by: James Bottomley <James.Bottomley@xxxxxxxxxxxxxxxxxxxxx>
> Reviewed-by: Ard Biesheuvel <ard.biesheuvel@xxxxxxxxxx> # crypto API parts
>
> ---
>
> v6: split into new patch, update config variable
> v7: add memzero_explicit
> ---
>  drivers/char/tpm/tpm2-sessions.c | 400 +++++++++++++++++++++++++++++++
>  include/linux/tpm.h              |  69 ++++++
>  2 files changed, 469 insertions(+)
>
> diff --git a/drivers/char/tpm/tpm2-sessions.c b/drivers/char/tpm/tpm2-sessions.c
> index 9eb420d8e530..9d6da0c9652f 100644
> --- a/drivers/char/tpm/tpm2-sessions.c
> +++ b/drivers/char/tpm/tpm2-sessions.c
> @@ -54,6 +54,18 @@
>   *	handles because handles have to be processed specially when
>   *	calculating the HMAC.  In particular, for NV, volatile and
>   *	permanent objects you now need to provide the name.
> + * tpm_buf_append_hmac_session() which appends the hmac session to the
> + *	buf in the same way tpm_buf_append_auth does().
> + * tpm_buf_fill_hmac_session() This calculates the correct hash and
> + *	places it in the buffer.  It must be called after the complete
> + *	command buffer is finalized so it can fill in the correct HMAC
> + *	based on the parameters.
> + * tpm_buf_check_hmac_response() which checks the session response in
> + *	the buffer and calculates what it should be.  If there's a
> + *	mismatch it will log a warning and return an error.  If
> + *	tpm_buf_append_hmac_session() did not specify
> + *	TPM_SA_CONTINUE_SESSION then the session will be closed (if it
> + *	hasn't been consumed) and the auth structure freed.
>   */
>  
>  #include "tpm.h"
> @@ -110,7 +122,23 @@ struct tpm2_auth {
>  		/* scratch for key + IV */
>  		u8 scratch[AES_KEYBYTES + AES_BLOCK_SIZE];
>  	};
> +	/*
> +	 * the session key and passphrase are the same size as the
> +	 * name digest (sha256 again).  The session key is constant
> +	 * for the use of the session and the passphrase can change
> +	 * with every invocation.
> +	 *
> +	 * Note: these fields must be adjacent and in this order
> +	 * because several HMAC/KDF schemes use the combination of the
> +	 * session_key and passphrase.
> +	 */
>  	u8 session_key[SHA256_DIGEST_SIZE];
> +	u8 passphrase[SHA256_DIGEST_SIZE];
> +	int passphraselen;
> +	struct crypto_aes_ctx aes_ctx;
> +	/* saved session attributes */

nit: "Saved session attributes:"

This makes just dead obvious that what  follows are what we are
referring to.

> +	u8 attrs;
> +	__be32 ordinal;
>  	/* 3 names of handles: name_h is handle, name is name of handle */
>  	u32 name_h[AUTH_MAX_NAMES];
>  	u8 name[AUTH_MAX_NAMES][2 + SHA512_DIGEST_SIZE];
> @@ -306,6 +334,230 @@ static void tpm_buf_append_salt(struct tpm_buf *buf, struct tpm_chip *chip)
>  	crypto_free_kpp(kpp);
>  }
>  
> +/**
> + * tpm_buf_append_hmac_session() - append a TPM session element
                                      ~
				      A

At least in the documentation these start with capital letter.


> + * @chip: the TPM chip structure
> + * @buf: The buffer to be appended
> + * @attributes: The session attributes
> + * @passphrase: The session authority (NULL if none)
> + * @passphraselen: The length of the session authority (0 if none)

passphrase_len

> + *
> + * This fills in a session structure in the TPM command buffer, except
> + * for the HMAC which cannot be computed until the command buffer is
> + * complete.  The type of session is controlled by the @attributes,
> + * the main ones of which are TPM2_SA_CONTINUE_SESSION which means the
> + * session won't terminate after tpm_buf_check_hmac_response(),
> + * TPM2_SA_DECRYPT which means this buffers first parameter should be
> + * encrypted with a session key and TPM2_SA_ENCRYPT, which means the
> + * response buffer's first parameter needs to be decrypted (confusing,
> + * but the defines are written from the point of view of the TPM).
> + *
> + * Any session appended by this command must be finalized by calling
> + * tpm_buf_fill_hmac_session() otherwise the HMAC will be incorrect
> + * and the TPM will reject the command.
> + *
> + * As with most tpm_buf operations, success is assumed because failure
> + * will be caused by an incorrect programming model and indicated by a
> + * kernel message.
> + */
> +void tpm_buf_append_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf,
> +				 u8 attributes, u8 *passphrase,
> +				 int passphraselen)
> +{
> +	u8 nonce[SHA256_DIGEST_SIZE];
> +	u32 len;
> +	struct tpm2_auth *auth = chip->auth;

re-order

> +
> +	/*
> +	 * The Architecture Guide requires us to strip trailing zeros
> +	 * before computing the HMAC
> +	 */
> +	while (passphrase && passphraselen > 0
> +	       && passphrase[passphraselen - 1] == '\0')
> +		passphraselen--;
> +
> +	auth->attrs = attributes;
> +	auth->passphraselen = passphraselen;
> +	if (passphraselen)
> +		memcpy(auth->passphrase, passphrase, passphraselen);
> +
> +	if (auth->session != tpm_buf_length(buf)) {
> +		/* we're not the first session */
> +		len = get_unaligned_be32(&buf->data[auth->session]);
> +		if (4 + len + auth->session != tpm_buf_length(buf)) {
> +			WARN(1, "session length mismatch, cannot append");
> +			return;
> +		}
> +
> +		/* add our new session */
> +		len += 9 + 2 * SHA256_DIGEST_SIZE;
> +		put_unaligned_be32(len, &buf->data[auth->session]);
> +	} else {
> +		tpm_buf_append_u32(buf, 9 + 2 * SHA256_DIGEST_SIZE);
> +	}
> +
> +	/* random number for our nonce */
> +	get_random_bytes(nonce, sizeof(nonce));
> +	memcpy(auth->our_nonce, nonce, sizeof(nonce));
> +	tpm_buf_append_u32(buf, auth->handle);
> +	/* our new nonce */
> +	tpm_buf_append_u16(buf, SHA256_DIGEST_SIZE);
> +	tpm_buf_append(buf, nonce, SHA256_DIGEST_SIZE);
> +	tpm_buf_append_u8(buf, auth->attrs);
> +	/* and put a placeholder for the hmac */
> +	tpm_buf_append_u16(buf, SHA256_DIGEST_SIZE);
> +	tpm_buf_append(buf, nonce, SHA256_DIGEST_SIZE);
> +}
> +EXPORT_SYMBOL(tpm_buf_append_hmac_session);
> +
> +/**
> + * tpm_buf_fill_hmac_session() - finalize the session HMAC
> + * @chip: the TPM chip structure
> + * @buf: The buffer to be appended
> + *
> + * This command must not be called until all of the parameters have
> + * been appended to @buf otherwise the computed HMAC will be
> + * incorrect.
> + *
> + * This function computes and fills in the session HMAC using the
> + * session key and, if TPM2_SA_DECRYPT was specified, computes the
> + * encryption key and encrypts the first parameter of the command
> + * buffer with it.
> + *
> + * As with most tpm_buf operations, success is assumed because failure
> + * will be caused by an incorrect programming model and indicated by a
> + * kernel message.
> + */
> +void tpm_buf_fill_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf)
> +{
> +	u32 cc, handles, val;
> +	struct tpm2_auth *auth = chip->auth;
> +	int i;
> +	struct tpm_header *head = (struct tpm_header *)buf->data;
> +	off_t offset_s = TPM_HEADER_SIZE, offset_p;
> +	u8 *hmac = NULL;
> +	u32 attrs;
> +	u8 cphash[SHA256_DIGEST_SIZE];
> +	struct sha256_state sctx;


definitely re-order

> +
> +	/* save the command code in BE format */
> +	auth->ordinal = head->ordinal;
> +
> +	cc = be32_to_cpu(head->ordinal);
> +
> +	i = tpm2_find_cc(chip, cc);
> +	if (i < 0) {
> +		dev_err(&chip->dev, "Command 0x%x not found in TPM\n", cc);
> +		return;
> +	}
> +	attrs = chip->cc_attrs_tbl[i];
> +
> +	handles = (attrs >> TPM2_CC_ATTR_CHANDLES) & GENMASK(2, 0);
> +
> +	/*
> +	 * just check the names, it's easy to make mistakes.  This
> +	 * would happen if someone added a handle via
> +	 * tpm_buf_append_u32() instead of tpm_buf_append_name()
> +	 */
> +	for (i = 0; i < handles; i++) {
> +		u32 handle = tpm_buf_read_u32(buf, &offset_s);
> +
> +		if (auth->name_h[i] != handle) {
> +			dev_err(&chip->dev, "TPM: handle %d wrong for name\n",
> +				  i);
> +			return;
> +		}
> +	}
> +	/* point offset_s to the start of the sessions */
> +	val = tpm_buf_read_u32(buf, &offset_s);
> +	/* point offset_p to the start of the parameters */
> +	offset_p = offset_s + val;
> +	for (i = 1; offset_s < offset_p; i++) {
> +		u32 handle = tpm_buf_read_u32(buf, &offset_s);
> +		u16 len;
> +		u8 a;
> +
> +		/* nonce (already in auth) */
> +		len = tpm_buf_read_u16(buf, &offset_s);
> +		offset_s += len;
> +
> +		a = tpm_buf_read_u8(buf, &offset_s);
> +
> +		len = tpm_buf_read_u16(buf, &offset_s);
> +		if (handle == auth->handle && auth->attrs == a) {
> +			hmac = &buf->data[offset_s];
> +			/*
> +			 * save our session number so we know which
> +			 * session in the response belongs to us
> +			 */
> +			auth->session = i;
> +		}
> +
> +		offset_s += len;
> +	}
> +	if (offset_s != offset_p) {
> +		dev_err(&chip->dev, "TPM session length is incorrect\n");
> +		return;
> +	}
> +	if (!hmac) {
> +		dev_err(&chip->dev, "TPM could not find HMAC session\n");
> +		return;
> +	}
> +
> +	/* encrypt before HMAC */
> +	if (auth->attrs & TPM2_SA_DECRYPT) {
> +		u16 len;
> +
> +		/* need key and IV */
> +		KDFa(auth->session_key, SHA256_DIGEST_SIZE
> +		     + auth->passphraselen, "CFB", auth->our_nonce,
> +		     auth->tpm_nonce, AES_KEYBYTES + AES_BLOCK_SIZE,
> +		     auth->scratch);
> +
> +		len = tpm_buf_read_u16(buf, &offset_p);
> +		aes_expandkey(&auth->aes_ctx, auth->scratch, AES_KEYBYTES);
> +		aescfb_encrypt(&auth->aes_ctx, &buf->data[offset_p],
> +			       &buf->data[offset_p], len,
> +			       auth->scratch + AES_KEYBYTES);
> +		/* reset p to beginning of parameters for HMAC */
> +		offset_p -= 2;
> +	}
> +
> +	sha256_init(&sctx);
> +	/* ordinal is already BE */
> +	sha256_update(&sctx, (u8 *)&head->ordinal, sizeof(head->ordinal));
> +	/* add the handle names */
> +	for (i = 0; i < handles; i++) {
> +		enum tpm2_mso_type mso = tpm2_handle_mso(auth->name_h[i]);
> +
> +		if (mso == TPM2_MSO_PERSISTENT ||
> +		    mso == TPM2_MSO_VOLATILE ||
> +		    mso == TPM2_MSO_NVRAM) {
> +			sha256_update(&sctx, auth->name[i],
> +				      name_size(auth->name[i]));
> +		} else {
> +			__be32 h = cpu_to_be32(auth->name_h[i]);
> +
> +			sha256_update(&sctx, (u8 *)&h, 4);
> +		}
> +	}
> +	if (offset_s != tpm_buf_length(buf))
> +		sha256_update(&sctx, &buf->data[offset_s],
> +			      tpm_buf_length(buf) - offset_s);
> +	sha256_final(&sctx, cphash);
> +
> +	/* now calculate the hmac */
> +	hmac_init(&sctx, auth->session_key, sizeof(auth->session_key)
> +		  + auth->passphraselen);
> +	sha256_update(&sctx, cphash, sizeof(cphash));
> +	sha256_update(&sctx, auth->our_nonce, sizeof(auth->our_nonce));
> +	sha256_update(&sctx, auth->tpm_nonce, sizeof(auth->tpm_nonce));
> +	sha256_update(&sctx, &auth->attrs, 1);
> +	hmac_final(&sctx, auth->session_key, sizeof(auth->session_key)
> +		   + auth->passphraselen, hmac);
> +}
> +EXPORT_SYMBOL(tpm_buf_fill_hmac_session);
> +
>  static int tpm2_parse_read_public(char *name, struct tpm_buf *buf)
>  {
>  	struct tpm_header *head = (struct tpm_header *)buf->data;
> @@ -403,6 +655,154 @@ void tpm_buf_append_name(struct tpm_chip *chip, struct tpm_buf *buf,
>  		memcpy(auth->name[slot], name, name_size(name));
>  }
>  EXPORT_SYMBOL(tpm_buf_append_name);
> +
> +/**
> + * tpm_buf_check_hmac_response() - check the TPM return HMAC for correctness
> + * @chip: the TPM chip structure
> + * @buf: the original command buffer (which now contains the response)
> + * @rc: the return code from tpm_transmit_cmd
> + *
> + * If @rc is non zero, @buf may not contain an actual return, so @rc
> + * is passed through as the return and the session cleaned up and
> + * de-allocated if required (this is required if
> + * TPM2_SA_CONTINUE_SESSION was not specified as a session flag).
> + *
> + * If @rc is zero, the response HMAC is computed against the returned
> + * @buf and matched to the TPM one in the session area.  If there is a
> + * mismatch, an error is logged and -EINVAL returned.
> + *
> + * The reason for this is that the command issue and HMAC check
> + * sequence should look like:
> + *
> + *	rc = tpm_transmit_cmd(...);
> + *	rc = tpm_buf_check_hmac_response(&buf, auth, rc);
> + *	if (rc)
> + *		...
> + *
> + * Which is easily layered into the current contrl flow.
> + *
> + * Returns: 0 on success or an error.
> + */
> +int tpm_buf_check_hmac_response(struct tpm_chip *chip, struct tpm_buf *buf,
> +				int rc)
> +{
> +	struct tpm_header *head = (struct tpm_header *)buf->data;
> +	struct tpm2_auth *auth = chip->auth;
> +	off_t offset_s, offset_p;
> +	u8 rphash[SHA256_DIGEST_SIZE];
> +	u32 attrs;
> +	struct sha256_state sctx;
> +	u16 tag = be16_to_cpu(head->tag);
> +	u32 cc = be32_to_cpu(auth->ordinal);
> +	int parm_len, len, i, handles;

ditto

> +
> +	if (auth->session >= TPM_HEADER_SIZE) {
> +		WARN(1, "tpm session not filled correctly\n");
> +		goto out;
> +	}
> +
> +	if (rc != 0)
> +		/* pass non success rc through and close the session */
> +		goto out;
> +
> +	rc = -EINVAL;
> +	if (tag != TPM2_ST_SESSIONS) {
> +		dev_err(&chip->dev, "TPM: HMAC response check has no sessions tag\n");
> +		goto out;
> +	}
> +
> +	i = tpm2_find_cc(chip, cc);
> +	if (i < 0)
> +		goto out;
> +	attrs = chip->cc_attrs_tbl[i];
> +	handles = (attrs >> TPM2_CC_ATTR_RHANDLE) & 1;
> +
> +	/* point to area beyond handles */
> +	offset_s = TPM_HEADER_SIZE + handles * 4;
> +	parm_len = tpm_buf_read_u32(buf, &offset_s);
> +	offset_p = offset_s;
> +	offset_s += parm_len;
> +	/* skip over any sessions before ours */
> +	for (i = 0; i < auth->session - 1; i++) {
> +		len = tpm_buf_read_u16(buf, &offset_s);
> +		offset_s += len + 1;
> +		len = tpm_buf_read_u16(buf, &offset_s);
> +		offset_s += len;
> +	}
> +	/* TPM nonce */
> +	len = tpm_buf_read_u16(buf, &offset_s);
> +	if (offset_s + len > tpm_buf_length(buf))
> +		goto out;
> +	if (len != SHA256_DIGEST_SIZE)
> +		goto out;
> +	memcpy(auth->tpm_nonce, &buf->data[offset_s], len);
> +	offset_s += len;
> +	attrs = tpm_buf_read_u8(buf, &offset_s);
> +	len = tpm_buf_read_u16(buf, &offset_s);
> +	if (offset_s + len != tpm_buf_length(buf))
> +		goto out;
> +	if (len != SHA256_DIGEST_SIZE)
> +		goto out;
> +	/*
> +	 * offset_s points to the HMAC. now calculate comparison, beginning
> +	 * with rphash
> +	 */
> +	sha256_init(&sctx);
> +	/* yes, I know this is now zero, but it's what the standard says */
> +	sha256_update(&sctx, (u8 *)&head->return_code,
> +		      sizeof(head->return_code));
> +	/* ordinal is already BE */
> +	sha256_update(&sctx, (u8 *)&auth->ordinal, sizeof(auth->ordinal));
> +	sha256_update(&sctx, &buf->data[offset_p], parm_len);
> +	sha256_final(&sctx, rphash);
> +
> +	/* now calculate the hmac */
> +	hmac_init(&sctx, auth->session_key, sizeof(auth->session_key)
> +		  + auth->passphraselen);
> +	sha256_update(&sctx, rphash, sizeof(rphash));
> +	sha256_update(&sctx, auth->tpm_nonce, sizeof(auth->tpm_nonce));
> +	sha256_update(&sctx, auth->our_nonce, sizeof(auth->our_nonce));
> +	sha256_update(&sctx, &auth->attrs, 1);
> +	/* we're done with the rphash, so put our idea of the hmac there */
> +	hmac_final(&sctx, auth->session_key, sizeof(auth->session_key)
> +		   + auth->passphraselen, rphash);
> +	if (memcmp(rphash, &buf->data[offset_s], SHA256_DIGEST_SIZE) == 0) {
> +		rc = 0;
> +	} else {
> +		dev_err(&chip->dev, "TPM: HMAC check failed\n");
> +		goto out;
> +	}
> +
> +	/* now do response decryption */
> +	if (auth->attrs & TPM2_SA_ENCRYPT) {
> +		/* need key and IV */
> +		KDFa(auth->session_key, SHA256_DIGEST_SIZE
> +		     + auth->passphraselen, "CFB", auth->tpm_nonce,
> +		     auth->our_nonce, AES_KEYBYTES + AES_BLOCK_SIZE,
> +		     auth->scratch);

OK, since there is multiple patches with KDF* dep the KDF functions
should be their own separate patch not glued into any patch that uses
them.

> +
> +		len = tpm_buf_read_u16(buf, &offset_p);
> +		aes_expandkey(&auth->aes_ctx, auth->scratch, AES_KEYBYTES);
> +		aescfb_decrypt(&auth->aes_ctx, &buf->data[offset_p],
> +			       &buf->data[offset_p], len,
> +			       auth->scratch + AES_KEYBYTES);
> +	}
> +
> + out:
> +	if ((auth->attrs & TPM2_SA_CONTINUE_SESSION) == 0) {
> +		if (rc)
> +			/* manually close the session if it wasn't consumed */
> +			tpm2_flush_context(chip, auth->handle);
> +		memzero_explicit(auth, sizeof(*auth));
> +	} else {
> +		/* reset for next use  */
> +		auth->session = TPM_HEADER_SIZE;
> +	}
> +
> +	return rc;
> +}
> +EXPORT_SYMBOL(tpm_buf_check_hmac_response);
> +
>  /**
>   * tpm2_end_auth_session() - kill the allocated auth session
>   * @chip: the TPM chip structure
> diff --git a/include/linux/tpm.h b/include/linux/tpm.h
> index 9b0b0d3c0d62..9c608fac8935 100644
> --- a/include/linux/tpm.h
> +++ b/include/linux/tpm.h
> @@ -490,8 +490,25 @@ static inline void tpm_buf_append_empty_auth(struct tpm_buf *buf, u32 handle)
>  int tpm2_start_auth_session(struct tpm_chip *chip);
>  void tpm_buf_append_name(struct tpm_chip *chip, struct tpm_buf *buf,
>  			 u32 handle, u8 *name);
> +void tpm_buf_append_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf,
> +				 u8 attributes, u8 *passphrase,
> +				 int passphraselen);
> +static inline void tpm_buf_append_hmac_session_opt(struct tpm_chip *chip,
> +						   struct tpm_buf *buf,
> +						   u8 attributes,
> +						   u8 *passphrase,
> +						   int passphraselen)
> +{
> +	tpm_buf_append_hmac_session(chip, buf, attributes, passphrase,
> +				    passphraselen);
> +}
> +void tpm_buf_fill_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf);
> +int tpm_buf_check_hmac_response(struct tpm_chip *chip, struct tpm_buf *buf,
> +				int rc);
>  void tpm2_end_auth_session(struct tpm_chip *chip);
>  #else
> +#include <asm/unaligned.h>
> +
>  static inline int tpm2_start_auth_session(struct tpm_chip *chip)
>  {
>  	return 0;
> @@ -507,6 +524,58 @@ static inline void tpm_buf_append_name(struct tpm_chip *chip,
>  	/* count the number of handles in the upper bits of flags */
>  	buf->handles++;
>  }
> +static inline void tpm_buf_append_hmac_session(struct tpm_chip *chip,
> +					       struct tpm_buf *buf,
> +					       u8 attributes, u8 *passphrase,
> +					       int passphraselen)
> +{
> +	/* offset tells us where the sessions area begins */
> +	int offset = buf->handles * 4 + TPM_HEADER_SIZE;
> +	u32 len = 9 + passphraselen;
> +
> +	if (tpm_buf_length(buf) != offset) {
> +		/* not the first session so update the existing length */
> +		len += get_unaligned_be32(&buf->data[offset]);
> +		put_unaligned_be32(len, &buf->data[offset]);
> +	} else {
> +		tpm_buf_append_u32(buf, len);
> +	}
> +	/* auth handle */
> +	tpm_buf_append_u32(buf, TPM2_RS_PW);
> +	/* nonce */
> +	tpm_buf_append_u16(buf, 0);
> +	/* attributes */
> +	tpm_buf_append_u8(buf, 0);
> +	/* passphrase */
> +	tpm_buf_append_u16(buf, passphraselen);
> +	tpm_buf_append(buf, passphrase, passphraselen);
> +}
> +static inline void tpm_buf_append_hmac_session_opt(struct tpm_chip *chip,
> +						   struct tpm_buf *buf,
> +						   u8 attributes,
> +						   u8 *passphrase,
> +						   int passphraselen)
> +{
> +	int offset = buf->handles * 4 + TPM_HEADER_SIZE;
> +	struct tpm_header *head = (struct tpm_header *) buf->data;
> +
> +	/*
> +	 * if the only sessions are optional, the command tag
> +	 * must change to TPM2_ST_NO_SESSIONS
> +	 */
> +	if (tpm_buf_length(buf) == offset)
> +		head->tag = cpu_to_be16(TPM2_ST_NO_SESSIONS);
> +}
> +static inline void tpm_buf_fill_hmac_session(struct tpm_chip *chip,
> +					     struct tpm_buf *buf)
> +{
> +}
> +static inline int tpm_buf_check_hmac_response(struct tpm_chip *chip,
> +					      struct tpm_buf *buf,
> +					      int rc)
> +{
> +	return rc;
> +}
>  #endif	/* CONFIG_TCG_TPM2_HMAC */
>  
>  #endif


BR, Jarkko





[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux Kernel]     [Linux Kernel Hardening]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux SCSI]

  Powered by Linux