Skip to content

Commit d0a25bb

Browse files
jejbjarkkojs
authored andcommitted
tpm: Add HMAC session name/handle append
Add tpm2_append_name() for appending to the handle area of the TPM command. When TPM_BUS_SECURITY is enabled and HMAC sessions are in use this adds the standard u32 handle to the buffer but additionally records the name of the object which must be used as part of the HMAC computation. The name of certain object types (volatile and permanent handles and NV indexes) is a hash of the public area of the object. Since this hash is not known ahead of time, it must be requested from the TPM using TPM2_ReadPublic() (which cannot be HMAC protected, but if an interposer lies about it, the HMAC check will fail and the problem will be detected). Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com> Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> # crypto API parts Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org> Tested-by: Jarkko Sakkinen <jarkko@kernel.org> Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
1 parent 699e3ef commit d0a25bb

2 files changed

Lines changed: 155 additions & 0 deletions

File tree

drivers/char/tpm/tpm2-sessions.c

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@
4949
* Under normal operation this function is done by
5050
* tpm_buf_check_hmac_response(), so this is only to be used on
5151
* error legs where the latter is not executed.
52+
* tpm_buf_append_name() to add a handle to the buffer. This must be
53+
* used in place of the usual tpm_buf_append_u32() for adding
54+
* handles because handles have to be processed specially when
55+
* calculating the HMAC. In particular, for NV, volatile and
56+
* permanent objects you now need to provide the name.
5257
*/
5358

5459
#include "tpm.h"
@@ -60,6 +65,9 @@
6065
#include <crypto/hash.h>
6166
#include <crypto/hmac.h>
6267

68+
/* maximum number of names the TPM must remember for authorization */
69+
#define AUTH_MAX_NAMES 3
70+
6371
/*
6472
* This is the structure that carries all the auth information (like
6573
* session handle, nonces, session key and auth) from use to use it is
@@ -96,8 +104,31 @@ struct tpm2_auth {
96104
u8 scratch[AES_KEY_BYTES + AES_BLOCK_SIZE];
97105
};
98106
u8 session_key[SHA256_DIGEST_SIZE];
107+
108+
/*
109+
* memory for three authorization handles. We know them by
110+
* handle, but they are part of the session by name, which
111+
* we must compute and remember
112+
*/
113+
u32 name_h[AUTH_MAX_NAMES];
114+
u8 name[AUTH_MAX_NAMES][2 + SHA512_DIGEST_SIZE];
99115
};
100116

117+
/*
118+
* Name Size based on TPM algorithm (assumes no hash bigger than 255)
119+
*/
120+
static u8 name_size(const u8 *name)
121+
{
122+
static u8 size_map[] = {
123+
[TPM_ALG_SHA1] = SHA1_DIGEST_SIZE,
124+
[TPM_ALG_SHA256] = SHA256_DIGEST_SIZE,
125+
[TPM_ALG_SHA384] = SHA384_DIGEST_SIZE,
126+
[TPM_ALG_SHA512] = SHA512_DIGEST_SIZE,
127+
};
128+
u16 alg = get_unaligned_be16(name);
129+
return size_map[alg] + 2;
130+
}
131+
101132
/*
102133
* It turns out the crypto hmac(sha256) is hard for us to consume
103134
* because it assumes a fixed key and the TPM seems to change the key
@@ -277,6 +308,104 @@ static void tpm_buf_append_salt(struct tpm_buf *buf, struct tpm_chip *chip)
277308
out:
278309
crypto_free_kpp(kpp);
279310
}
311+
312+
static int tpm2_parse_read_public(char *name, struct tpm_buf *buf)
313+
{
314+
struct tpm_header *head = (struct tpm_header *)buf->data;
315+
off_t offset = TPM_HEADER_SIZE;
316+
u32 tot_len = be32_to_cpu(head->length);
317+
u32 val;
318+
319+
/* we're starting after the header so adjust the length */
320+
tot_len -= TPM_HEADER_SIZE;
321+
322+
/* skip public */
323+
val = tpm_buf_read_u16(buf, &offset);
324+
if (val > tot_len)
325+
return -EINVAL;
326+
offset += val;
327+
/* name */
328+
val = tpm_buf_read_u16(buf, &offset);
329+
if (val != name_size(&buf->data[offset]))
330+
return -EINVAL;
331+
memcpy(name, &buf->data[offset], val);
332+
/* forget the rest */
333+
return 0;
334+
}
335+
336+
static int tpm2_read_public(struct tpm_chip *chip, u32 handle, char *name)
337+
{
338+
struct tpm_buf buf;
339+
int rc;
340+
341+
rc = tpm_buf_init(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_READ_PUBLIC);
342+
if (rc)
343+
return rc;
344+
345+
tpm_buf_append_u32(&buf, handle);
346+
rc = tpm_transmit_cmd(chip, &buf, 0, "read public");
347+
if (rc == TPM2_RC_SUCCESS)
348+
rc = tpm2_parse_read_public(name, &buf);
349+
350+
tpm_buf_destroy(&buf);
351+
352+
return rc;
353+
}
354+
355+
/**
356+
* tpm_buf_append_name() - add a handle area to the buffer
357+
* @chip: the TPM chip structure
358+
* @buf: The buffer to be appended
359+
* @handle: The handle to be appended
360+
* @name: The name of the handle (may be NULL)
361+
*
362+
* In order to compute session HMACs, we need to know the names of the
363+
* objects pointed to by the handles. For most objects, this is simply
364+
* the actual 4 byte handle or an empty buf (in these cases @name
365+
* should be NULL) but for volatile objects, permanent objects and NV
366+
* areas, the name is defined as the hash (according to the name
367+
* algorithm which should be set to sha256) of the public area to
368+
* which the two byte algorithm id has been appended. For these
369+
* objects, the @name pointer should point to this. If a name is
370+
* required but @name is NULL, then TPM2_ReadPublic() will be called
371+
* on the handle to obtain the name.
372+
*
373+
* As with most tpm_buf operations, success is assumed because failure
374+
* will be caused by an incorrect programming model and indicated by a
375+
* kernel message.
376+
*/
377+
void tpm_buf_append_name(struct tpm_chip *chip, struct tpm_buf *buf,
378+
u32 handle, u8 *name)
379+
{
380+
enum tpm2_mso_type mso = tpm2_handle_mso(handle);
381+
struct tpm2_auth *auth = chip->auth;
382+
int slot;
383+
384+
slot = (tpm_buf_length(buf) - TPM_HEADER_SIZE)/4;
385+
if (slot >= AUTH_MAX_NAMES) {
386+
dev_err(&chip->dev, "TPM: too many handles\n");
387+
return;
388+
}
389+
WARN(auth->session != tpm_buf_length(buf),
390+
"name added in wrong place\n");
391+
tpm_buf_append_u32(buf, handle);
392+
auth->session += 4;
393+
394+
if (mso == TPM2_MSO_PERSISTENT ||
395+
mso == TPM2_MSO_VOLATILE ||
396+
mso == TPM2_MSO_NVRAM) {
397+
if (!name)
398+
tpm2_read_public(chip, handle, auth->name[slot]);
399+
} else {
400+
if (name)
401+
dev_err(&chip->dev, "TPM: Handle does not require name but one is specified\n");
402+
}
403+
404+
auth->name_h[slot] = handle;
405+
if (name)
406+
memcpy(auth->name[slot], name, name_size(name));
407+
}
408+
EXPORT_SYMBOL(tpm_buf_append_name);
280409
/**
281410
* tpm2_end_auth_session() - kill the allocated auth session
282411
* @chip: the TPM chip structure

include/linux/tpm.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,7 @@ enum tpm2_command_codes {
275275
TPM2_CC_CONTEXT_LOAD = 0x0161,
276276
TPM2_CC_CONTEXT_SAVE = 0x0162,
277277
TPM2_CC_FLUSH_CONTEXT = 0x0165,
278+
TPM2_CC_READ_PUBLIC = 0x0173,
278279
TPM2_CC_START_AUTH_SESS = 0x0176,
279280
TPM2_CC_VERIFY_SIGNATURE = 0x0177,
280281
TPM2_CC_GET_CAPABILITY = 0x017A,
@@ -292,6 +293,21 @@ enum tpm2_permanent_handles {
292293
TPM2_RS_PW = 0x40000009,
293294
};
294295

296+
/* Most Significant Octet for key types */
297+
enum tpm2_mso_type {
298+
TPM2_MSO_NVRAM = 0x01,
299+
TPM2_MSO_SESSION = 0x02,
300+
TPM2_MSO_POLICY = 0x03,
301+
TPM2_MSO_PERMANENT = 0x40,
302+
TPM2_MSO_VOLATILE = 0x80,
303+
TPM2_MSO_PERSISTENT = 0x81,
304+
};
305+
306+
static inline enum tpm2_mso_type tpm2_handle_mso(u32 handle)
307+
{
308+
return handle >> 24;
309+
}
310+
295311
enum tpm2_capabilities {
296312
TPM2_CAP_HANDLES = 1,
297313
TPM2_CAP_COMMANDS = 2,
@@ -492,6 +508,8 @@ static inline void tpm_buf_append_empty_auth(struct tpm_buf *buf, u32 handle)
492508
#ifdef CONFIG_TCG_TPM2_HMAC
493509

494510
int tpm2_start_auth_session(struct tpm_chip *chip);
511+
void tpm_buf_append_name(struct tpm_chip *chip, struct tpm_buf *buf,
512+
u32 handle, u8 *name);
495513
void tpm2_end_auth_session(struct tpm_chip *chip);
496514
#else
497515
static inline int tpm2_start_auth_session(struct tpm_chip *chip)
@@ -501,6 +519,14 @@ static inline int tpm2_start_auth_session(struct tpm_chip *chip)
501519
static inline void tpm2_end_auth_session(struct tpm_chip *chip)
502520
{
503521
}
522+
static inline void tpm_buf_append_name(struct tpm_chip *chip,
523+
struct tpm_buf *buf,
524+
u32 handle, u8 *name)
525+
{
526+
tpm_buf_append_u32(buf, handle);
527+
/* count the number of handles in the upper bits of flags */
528+
buf->handles++;
529+
}
504530
#endif /* CONFIG_TCG_TPM2_HMAC */
505531

506532
#endif

0 commit comments

Comments
 (0)