On Mon Apr 29, 2024 at 11:28 PM EEST, 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 immediately 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.bottom...@hansenpartnership.com>
> Reviewed-by: Ard Biesheuvel <ard.biesheu...@linaro.org> # crypto API parts
>
> ---
>
> v6: split into new patch, update config variable
> v7: add memzero_explicit
> v8: minor updates
> ---
>  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 99eb048f18c8..3c97d3d5e00e 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"
> @@ -103,7 +115,23 @@ struct tpm2_auth {
>               /* scratch for key + IV */
>               u8 scratch[AES_KEY_BYTES + 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 passphrase_len;
> +     struct crypto_aes_ctx aes_ctx;
> +     /* saved session attributes: */
> +     u8 attrs;
> +     __be32 ordinal;
>  
>       /*
>        * memory for three authorization handles.  We know them by
> @@ -309,6 +337,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
> + * @chip: the TPM chip structure
> + * @buf: The buffer to be appended
> + * @attributes: The session attributes
> + * @passphrase: The session authority (NULL if none)
> + * @passphrase_len: The length of the session authority (0 if none)
> + *
> + * 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 passphrase_len)
> +{
> +     u8 nonce[SHA256_DIGEST_SIZE];
> +     u32 len;
> +     struct tpm2_auth *auth = chip->auth;
> +
> +     /*
> +      * The Architecture Guide requires us to strip trailing zeros
> +      * before computing the HMAC
> +      */
> +     while (passphrase && passphrase_len > 0
> +            && passphrase[passphrase_len - 1] == '\0')
> +             passphrase_len--;
> +
> +     auth->attrs = attributes;
> +     auth->passphrase_len = passphrase_len;
> +     if (passphrase_len)
> +             memcpy(auth->passphrase, passphrase, passphrase_len);
> +
> +     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;
> +
> +     /* 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 */
> +             tpm2_KDFa(auth->session_key, SHA256_DIGEST_SIZE
> +                       + auth->passphrase_len, "CFB", auth->our_nonce,
> +                       auth->tpm_nonce, AES_KEY_BYTES + AES_BLOCK_SIZE,
> +                       auth->scratch);
> +
> +             len = tpm_buf_read_u16(buf, &offset_p);
> +             aes_expandkey(&auth->aes_ctx, auth->scratch, AES_KEY_BYTES);
> +             aescfb_encrypt(&auth->aes_ctx, &buf->data[offset_p],
> +                            &buf->data[offset_p], len,
> +                            auth->scratch + AES_KEY_BYTES);
> +             /* 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 */
> +     tpm2_hmac_init(&sctx, auth->session_key, sizeof(auth->session_key)
> +                    + auth->passphrase_len);
> +     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);
> +     tpm2_hmac_final(&sctx, auth->session_key, sizeof(auth->session_key)
> +                     + auth->passphrase_len, 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;
> @@ -406,6 +658,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;
> +
> +     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 */
> +     tpm2_hmac_init(&sctx, auth->session_key, sizeof(auth->session_key)
> +                    + auth->passphrase_len);
> +     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 */
> +     tpm2_hmac_final(&sctx, auth->session_key, sizeof(auth->session_key)
> +                     + auth->passphrase_len, 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 */
> +             tpm2_KDFa(auth->session_key, SHA256_DIGEST_SIZE
> +                       + auth->passphrase_len, "CFB", auth->tpm_nonce,
> +                       auth->our_nonce, AES_KEY_BYTES + AES_BLOCK_SIZE,
> +                       auth->scratch);
> +
> +             len = tpm_buf_read_u16(buf, &offset_p);
> +             aes_expandkey(&auth->aes_ctx, auth->scratch, AES_KEY_BYTES);
> +             aescfb_decrypt(&auth->aes_ctx, &buf->data[offset_p],
> +                            &buf->data[offset_p], len,
> +                            auth->scratch + AES_KEY_BYTES);
> +     }
> +
> + 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 31c2065fcd35..dd4d6a6158c4 100644
> --- a/include/linux/tpm.h
> +++ b/include/linux/tpm.h
> @@ -510,8 +510,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;
> @@ -527,6 +544,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

Reviewed-by: Jarkko Sakkinen <jar...@kernel.org>

BR, Jarkko

Reply via email to