drivers/char/tpm/tpm2-sessions.c

Source file repositories/reference/linux-study-clean/drivers/char/tpm/tpm2-sessions.c

File Facts

System
Linux kernel
Corpus path
drivers/char/tpm/tpm2-sessions.c
Extension
.c
Size
40682 bytes
Lines
1402
Domain
Driver Families
Bucket
drivers/char
Inferred role
Driver Families: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

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 aes_enckey aes_key;
	/* 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];
};

#ifdef CONFIG_TCG_TPM2_HMAC
/*
 * Name Size based on TPM algorithm (assumes no hash bigger than 255)
 */
static int name_size(const u8 *name)
{
	u16 hash_alg = get_unaligned_be16(name);

	switch (hash_alg) {
	case TPM_ALG_SHA1:
		return SHA1_DIGEST_SIZE + 2;
	case TPM_ALG_SHA256:
		return SHA256_DIGEST_SIZE + 2;
	case TPM_ALG_SHA384:
		return SHA384_DIGEST_SIZE + 2;
	case TPM_ALG_SHA512:
		return SHA512_DIGEST_SIZE + 2;
	default:
		pr_warn("tpm: unsupported name algorithm: 0x%04x\n", hash_alg);
		return -EINVAL;
	}
}

static int tpm2_read_public(struct tpm_chip *chip, u32 handle, void *name)
{
	u32 mso = tpm2_handle_mso(handle);
	off_t offset = TPM_HEADER_SIZE;
	int rc, name_size_alg;
	struct tpm_buf buf;

	if (mso != TPM2_MSO_PERSISTENT && mso != TPM2_MSO_VOLATILE &&
	    mso != TPM2_MSO_NVRAM) {
		memcpy(name, &handle, sizeof(u32));

Annotation

Implementation Notes