// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2018 James.Bottomley@HansenPartnership.com
*
* Cryptographic helper routines for handling TPM2 sessions for
* authorization HMAC and request response encryption.
*
* The idea is to ensure that every TPM command is HMAC protected by a
* session, meaning in-flight tampering would be detected and in
* addition all sensitive inputs and responses should be encrypted.
*
* The basic way this works is to use a TPM feature called salted
* sessions where a random secret used in session construction is
* encrypted to the public part of a known TPM key. The problem is we
* have no known keys, so initially a primary Elliptic Curve key is
* derived from the NULL seed (we use EC because most TPMs generate
* these keys much faster than RSA ones). The curve used is NIST_P256
* because that's now mandated to be present in 'TCG TPM v2.0
* Provisioning Guidance'
*
* Threat problems: the initial TPM2_CreatePrimary is not (and cannot
* be) session protected, so a clever Man in the Middle could return a
* public key they control to this command and from there intercept
* and decode all subsequent session based transactions. The kernel
* cannot mitigate this threat but, after boot, userspace can get
* proof this has not happened by asking the TPM to certify the NULL
* key. This certification would chain back to the TPM Endorsement
* Certificate and prove the NULL seed primary had not been tampered
* with and thus all sessions must have been cryptographically secure.
* To assist with this, the initial NULL seed public key name is made
* available in a sysfs file.
*
* Use of these functions:
*
* The design is all the crypto, hash and hmac gunk is confined in this
* file and never needs to be seen even by the kernel internal user. To
* the user there's an init function tpm2_sessions_init() that needs to
* be called once per TPM which generates the NULL seed primary key.
*
* These are the usage functions:
*
* tpm2_start_auth_session() which allocates the opaque auth structure
* and gets a session from the TPM. This must be called before
* any of the following functions. The session is protected by a
* session_key which is derived from a random salt value
* encrypted to the NULL seed.
* tpm2_end_auth_session() kills the session and frees the resources.
* Under normal operation this function is done by
* tpm_buf_check_hmac_response(), so this is only to be used on
* error legs where the latter is not executed.
* tpm_buf_append_name() to add a handle to the buffer. This must be
* used in place of the usual tpm_buf_append_u32() for adding
* 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"
#include <linux/random.h>
#include <linux/scatterlist.h>
#include <asm/unaligned.h>
#include <crypto/kpp.h>
#include <crypto/ecdh.h>
#include <crypto/hash.h>
#include <crypto/hmac.h>
/* maximum number of names the TPM must remember for authorization */
#define AUTH_MAX_NAMES 3
static int tpm2_create_primary(struct tpm_chip *chip, u32 hierarchy,
u32 *handle, u8 *name);
/*
* This is the structure that carries all the auth information (like
* session handle, nonces, session key and auth) from use to use it is
* designed to be opaque to anything outside.
*/
struct tpm2_auth {
u32 handle;
/*
* This has two meanings: before tpm_buf_fill_hmac_session()
* it marks the offset in the buffer of the start of the
* sessions (i.e. after all the handles). Once the buffer has
* been filled it markes the session number of our auth
* session so we can find it again in the response buffer.
*
* The two cases are distinguished because the first offset
* must always be greater than TPM_HEADER_SIZE and the second
* must be less than or equal to 5.
*/
u32 session;
/*
* the size here is variable and set by the size of our_nonce
* which must be between 16 and the name hash length. we set
* the maximum sha256 size for the greatest protection
*/
u8 our_nonce[SHA256_DIGEST_SIZE];
u8 tpm_nonce[SHA256_DIGEST_SIZE];
/*
* the salt is only used across the session command/response
* after that it can be used as a scratch area
*/
union {
u8 salt[EC_PT_SZ];
/* 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
* handle, but they are part of the session by name, which
* we must compute and remember
*/
u32 name_h[AUTH_MAX_NAMES];
u8 name[AUTH_MAX_NAMES][2 + SHA512_DIGEST_SIZE];
};
/*
* Name Size based on TPM algorithm (assumes no hash bigger than 255)
*/
static u8 name_size(const u8 *name