Skip to content

Commit a61809a

Browse files
committed
tpm: Address !chip->auth in tpm_buf_append_name()
Unless tpm_chip_bootstrap() was called by the driver, !chip->auth can cause a null derefence in tpm_buf_append_name(). Thus, address !chip->auth in tpm_buf_append_name() and remove the fallback implementation for !TCG_TPM2_HMAC. Cc: [email protected] # v6.10+ Reported-by: Stefan Berger <[email protected]> Closes: https://lore.kernel.org/linux-integrity/[email protected]/ Fixes: d0a25bb ("tpm: Add HMAC session name/handle append") Tested-by: Michael Ellerman <[email protected]> # ppc Signed-off-by: Jarkko Sakkinen <[email protected]>
1 parent 25ee48a commit a61809a

File tree

3 files changed

+131
-111
lines changed

3 files changed

+131
-111
lines changed

drivers/char/tpm/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ tpm-y += eventlog/common.o
1616
tpm-y += eventlog/tpm1.o
1717
tpm-y += eventlog/tpm2.o
1818
tpm-y += tpm-buf.o
19+
tpm-y += tpm2-sessions.o
1920

20-
tpm-$(CONFIG_TCG_TPM2_HMAC) += tpm2-sessions.o
2121
tpm-$(CONFIG_ACPI) += tpm_ppi.o eventlog/acpi.o
2222
tpm-$(CONFIG_EFI) += eventlog/efi.o
2323
tpm-$(CONFIG_OF) += eventlog/of.o

drivers/char/tpm/tpm2-sessions.c

Lines changed: 118 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,6 @@
8383
#define AES_KEY_BYTES AES_KEYSIZE_128
8484
#define AES_KEY_BITS (AES_KEY_BYTES*8)
8585

86-
static int tpm2_create_primary(struct tpm_chip *chip, u32 hierarchy,
87-
u32 *handle, u8 *name);
88-
8986
/*
9087
* This is the structure that carries all the auth information (like
9188
* session handle, nonces, session key and auth) from use to use it is
@@ -148,6 +145,7 @@ struct tpm2_auth {
148145
u8 name[AUTH_MAX_NAMES][2 + SHA512_DIGEST_SIZE];
149146
};
150147

148+
#ifdef CONFIG_TCG_TPM2_HMAC
151149
/*
152150
* Name Size based on TPM algorithm (assumes no hash bigger than 255)
153151
*/
@@ -163,6 +161,122 @@ static u8 name_size(const u8 *name)
163161
return size_map[alg] + 2;
164162
}
165163

164+
static int tpm2_parse_read_public(char *name, struct tpm_buf *buf)
165+
{
166+
struct tpm_header *head = (struct tpm_header *)buf->data;
167+
off_t offset = TPM_HEADER_SIZE;
168+
u32 tot_len = be32_to_cpu(head->length);
169+
u32 val;
170+
171+
/* we're starting after the header so adjust the length */
172+
tot_len -= TPM_HEADER_SIZE;
173+
174+
/* skip public */
175+
val = tpm_buf_read_u16(buf, &offset);
176+
if (val > tot_len)
177+
return -EINVAL;
178+
offset += val;
179+
/* name */
180+
val = tpm_buf_read_u16(buf, &offset);
181+
if (val != name_size(&buf->data[offset]))
182+
return -EINVAL;
183+
memcpy(name, &buf->data[offset], val);
184+
/* forget the rest */
185+
return 0;
186+
}
187+
188+
static int tpm2_read_public(struct tpm_chip *chip, u32 handle, char *name)
189+
{
190+
struct tpm_buf buf;
191+
int rc;
192+
193+
rc = tpm_buf_init(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_READ_PUBLIC);
194+
if (rc)
195+
return rc;
196+
197+
tpm_buf_append_u32(&buf, handle);
198+
rc = tpm_transmit_cmd(chip, &buf, 0, "read public");
199+
if (rc == TPM2_RC_SUCCESS)
200+
rc = tpm2_parse_read_public(name, &buf);
201+
202+
tpm_buf_destroy(&buf);
203+
204+
return rc;
205+
}
206+
#endif /* CONFIG_TCG_TPM2_HMAC */
207+
208+
/**
209+
* tpm_buf_append_name() - add a handle area to the buffer
210+
* @chip: the TPM chip structure
211+
* @buf: The buffer to be appended
212+
* @handle: The handle to be appended
213+
* @name: The name of the handle (may be NULL)
214+
*
215+
* In order to compute session HMACs, we need to know the names of the
216+
* objects pointed to by the handles. For most objects, this is simply
217+
* the actual 4 byte handle or an empty buf (in these cases @name
218+
* should be NULL) but for volatile objects, permanent objects and NV
219+
* areas, the name is defined as the hash (according to the name
220+
* algorithm which should be set to sha256) of the public area to
221+
* which the two byte algorithm id has been appended. For these
222+
* objects, the @name pointer should point to this. If a name is
223+
* required but @name is NULL, then TPM2_ReadPublic() will be called
224+
* on the handle to obtain the name.
225+
*
226+
* As with most tpm_buf operations, success is assumed because failure
227+
* will be caused by an incorrect programming model and indicated by a
228+
* kernel message.
229+
*/
230+
void tpm_buf_append_name(struct tpm_chip *chip, struct tpm_buf *buf,
231+
u32 handle, u8 *name)
232+
{
233+
#ifdef CONFIG_TCG_TPM2_HMAC
234+
enum tpm2_mso_type mso = tpm2_handle_mso(handle);
235+
struct tpm2_auth *auth;
236+
int slot;
237+
#endif
238+
239+
if (!tpm2_chip_auth(chip)) {
240+
tpm_buf_append_u32(buf, handle);
241+
/* count the number of handles in the upper bits of flags */
242+
buf->handles++;
243+
return;
244+
}
245+
246+
#ifdef CONFIG_TCG_TPM2_HMAC
247+
slot = (tpm_buf_length(buf) - TPM_HEADER_SIZE) / 4;
248+
if (slot >= AUTH_MAX_NAMES) {
249+
dev_err(&chip->dev, "TPM: too many handles\n");
250+
return;
251+
}
252+
auth = chip->auth;
253+
WARN(auth->session != tpm_buf_length(buf),
254+
"name added in wrong place\n");
255+
tpm_buf_append_u32(buf, handle);
256+
auth->session += 4;
257+
258+
if (mso == TPM2_MSO_PERSISTENT ||
259+
mso == TPM2_MSO_VOLATILE ||
260+
mso == TPM2_MSO_NVRAM) {
261+
if (!name)
262+
tpm2_read_public(chip, handle, auth->name[slot]);
263+
} else {
264+
if (name)
265+
dev_err(&chip->dev, "TPM: Handle does not require name but one is specified\n");
266+
}
267+
268+
auth->name_h[slot] = handle;
269+
if (name)
270+
memcpy(auth->name[slot], name, name_size(name));
271+
#endif
272+
}
273+
EXPORT_SYMBOL_GPL(tpm_buf_append_name);
274+
275+
#ifdef CONFIG_TCG_TPM2_HMAC
276+
277+
static int tpm2_create_primary(struct tpm_chip *chip, u32 hierarchy,
278+
u32 *handle, u8 *name);
279+
166280
/*
167281
* It turns out the crypto hmac(sha256) is hard for us to consume
168282
* because it assumes a fixed key and the TPM seems to change the key
@@ -567,104 +681,6 @@ void tpm_buf_fill_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf)
567681
}
568682
EXPORT_SYMBOL(tpm_buf_fill_hmac_session);
569683

570-
static int tpm2_parse_read_public(char *name, struct tpm_buf *buf)
571-
{
572-
struct tpm_header *head = (struct tpm_header *)buf->data;
573-
off_t offset = TPM_HEADER_SIZE;
574-
u32 tot_len = be32_to_cpu(head->length);
575-
u32 val;
576-
577-
/* we're starting after the header so adjust the length */
578-
tot_len -= TPM_HEADER_SIZE;
579-
580-
/* skip public */
581-
val = tpm_buf_read_u16(buf, &offset);
582-
if (val > tot_len)
583-
return -EINVAL;
584-
offset += val;
585-
/* name */
586-
val = tpm_buf_read_u16(buf, &offset);
587-
if (val != name_size(&buf->data[offset]))
588-
return -EINVAL;
589-
memcpy(name, &buf->data[offset], val);
590-
/* forget the rest */
591-
return 0;
592-
}
593-
594-
static int tpm2_read_public(struct tpm_chip *chip, u32 handle, char *name)
595-
{
596-
struct tpm_buf buf;
597-
int rc;
598-
599-
rc = tpm_buf_init(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_READ_PUBLIC);
600-
if (rc)
601-
return rc;
602-
603-
tpm_buf_append_u32(&buf, handle);
604-
rc = tpm_transmit_cmd(chip, &buf, 0, "read public");
605-
if (rc == TPM2_RC_SUCCESS)
606-
rc = tpm2_parse_read_public(name, &buf);
607-
608-
tpm_buf_destroy(&buf);
609-
610-
return rc;
611-
}
612-
613-
/**
614-
* tpm_buf_append_name() - add a handle area to the buffer
615-
* @chip: the TPM chip structure
616-
* @buf: The buffer to be appended
617-
* @handle: The handle to be appended
618-
* @name: The name of the handle (may be NULL)
619-
*
620-
* In order to compute session HMACs, we need to know the names of the
621-
* objects pointed to by the handles. For most objects, this is simply
622-
* the actual 4 byte handle or an empty buf (in these cases @name
623-
* should be NULL) but for volatile objects, permanent objects and NV
624-
* areas, the name is defined as the hash (according to the name
625-
* algorithm which should be set to sha256) of the public area to
626-
* which the two byte algorithm id has been appended. For these
627-
* objects, the @name pointer should point to this. If a name is
628-
* required but @name is NULL, then TPM2_ReadPublic() will be called
629-
* on the handle to obtain the name.
630-
*
631-
* As with most tpm_buf operations, success is assumed because failure
632-
* will be caused by an incorrect programming model and indicated by a
633-
* kernel message.
634-
*/
635-
void tpm_buf_append_name(struct tpm_chip *chip, struct tpm_buf *buf,
636-
u32 handle, u8 *name)
637-
{
638-
enum tpm2_mso_type mso = tpm2_handle_mso(handle);
639-
struct tpm2_auth *auth = chip->auth;
640-
int slot;
641-
642-
slot = (tpm_buf_length(buf) - TPM_HEADER_SIZE)/4;
643-
if (slot >= AUTH_MAX_NAMES) {
644-
dev_err(&chip->dev, "TPM: too many handles\n");
645-
return;
646-
}
647-
WARN(auth->session != tpm_buf_length(buf),
648-
"name added in wrong place\n");
649-
tpm_buf_append_u32(buf, handle);
650-
auth->session += 4;
651-
652-
if (mso == TPM2_MSO_PERSISTENT ||
653-
mso == TPM2_MSO_VOLATILE ||
654-
mso == TPM2_MSO_NVRAM) {
655-
if (!name)
656-
tpm2_read_public(chip, handle, auth->name[slot]);
657-
} else {
658-
if (name)
659-
dev_err(&chip->dev, "TPM: Handle does not require name but one is specified\n");
660-
}
661-
662-
auth->name_h[slot] = handle;
663-
if (name)
664-
memcpy(auth->name[slot], name, name_size(name));
665-
}
666-
EXPORT_SYMBOL(tpm_buf_append_name);
667-
668684
/**
669685
* tpm_buf_check_hmac_response() - check the TPM return HMAC for correctness
670686
* @chip: the TPM chip structure
@@ -1311,3 +1327,4 @@ int tpm2_sessions_init(struct tpm_chip *chip)
13111327

13121328
return rc;
13131329
}
1330+
#endif /* CONFIG_TCG_TPM2_HMAC */

include/linux/tpm.h

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -490,11 +490,22 @@ static inline void tpm_buf_append_empty_auth(struct tpm_buf *buf, u32 handle)
490490
{
491491
}
492492
#endif
493+
494+
static inline struct tpm2_auth *tpm2_chip_auth(struct tpm_chip *chip)
495+
{
493496
#ifdef CONFIG_TCG_TPM2_HMAC
497+
return chip->auth;
498+
#else
499+
return NULL;
500+
#endif
501+
}
494502

495-
int tpm2_start_auth_session(struct tpm_chip *chip);
496503
void tpm_buf_append_name(struct tpm_chip *chip, struct tpm_buf *buf,
497504
u32 handle, u8 *name);
505+
506+
#ifdef CONFIG_TCG_TPM2_HMAC
507+
508+
int tpm2_start_auth_session(struct tpm_chip *chip);
498509
void tpm_buf_append_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf,
499510
u8 attributes, u8 *passphrase,
500511
int passphraselen);
@@ -521,14 +532,6 @@ static inline int tpm2_start_auth_session(struct tpm_chip *chip)
521532
static inline void tpm2_end_auth_session(struct tpm_chip *chip)
522533
{
523534
}
524-
static inline void tpm_buf_append_name(struct tpm_chip *chip,
525-
struct tpm_buf *buf,
526-
u32 handle, u8 *name)
527-
{
528-
tpm_buf_append_u32(buf, handle);
529-
/* count the number of handles in the upper bits of flags */
530-
buf->handles++;
531-
}
532535
static inline void tpm_buf_append_hmac_session(struct tpm_chip *chip,
533536
struct tpm_buf *buf,
534537
u8 attributes, u8 *passphrase,

0 commit comments

Comments
 (0)