Skip to content

Commit c3465a3

Browse files
author
Jarkko Sakkinen
committed
tpm: move tpm_validate_commmand() to tpm2-space.c
Move tpm_validate_command() to tpm2-space.c and make it part of the tpm2_prepare_space() flow. Make cc resolution as part of the TPM space functionality in order to detach it from rest of the tpm_transmit() flow. Cc: James Bottomley <James.Bottomley@HansenPartnership.com> Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> Reviewed-by: Stefan Berger <stefanb@linux.ibm.com> Tested-by: Stefan Berger <stefanb@linux.ibm.com> Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com> Reviewed-by: James Bottomley <James.Bottomley@HansenPartnership.com> Tested-by: Alexander Steffen <Alexander.Steffen@infineon.com>
1 parent 304ff67 commit c3465a3

File tree

3 files changed

+66
-64
lines changed

3 files changed

+66
-64
lines changed

drivers/char/tpm/tpm-interface.c

Lines changed: 15 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -62,45 +62,6 @@ unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal)
6262
}
6363
EXPORT_SYMBOL_GPL(tpm_calc_ordinal_duration);
6464

65-
static int tpm_validate_command(struct tpm_chip *chip, struct tpm_space *space,
66-
const void *cmd, size_t len)
67-
{
68-
const struct tpm_header *header = cmd;
69-
int i;
70-
u32 cc;
71-
u32 attrs;
72-
unsigned int nr_handles;
73-
74-
if (len < TPM_HEADER_SIZE)
75-
return -EINVAL;
76-
77-
if (!space)
78-
return 0;
79-
80-
if (chip->flags & TPM_CHIP_FLAG_TPM2 && chip->nr_commands) {
81-
cc = be32_to_cpu(header->ordinal);
82-
83-
i = tpm2_find_cc(chip, cc);
84-
if (i < 0) {
85-
dev_dbg(&chip->dev, "0x%04X is an invalid command\n",
86-
cc);
87-
return -EOPNOTSUPP;
88-
}
89-
90-
attrs = chip->cc_attrs_tbl[i];
91-
nr_handles =
92-
4 * ((attrs >> TPM2_CC_ATTR_CHANDLES) & GENMASK(2, 0));
93-
if (len < TPM_HEADER_SIZE + 4 * nr_handles)
94-
goto err_len;
95-
}
96-
97-
return 0;
98-
err_len:
99-
dev_dbg(&chip->dev,
100-
"%s: insufficient command length %zu", __func__, len);
101-
return -EINVAL;
102-
}
103-
10465
static int tpm_request_locality(struct tpm_chip *chip, unsigned int flags)
10566
{
10667
int rc;
@@ -168,20 +129,8 @@ static ssize_t tpm_try_transmit(struct tpm_chip *chip, struct tpm_space *space,
168129
u32 count, ordinal;
169130
unsigned long stop;
170131

171-
rc = tpm_validate_command(chip, space, buf, bufsiz);
172-
if (rc == -EINVAL)
173-
return rc;
174-
/*
175-
* If the command is not implemented by the TPM, synthesize a
176-
* response with a TPM2_RC_COMMAND_CODE return for user-space.
177-
*/
178-
if (rc == -EOPNOTSUPP) {
179-
header->length = cpu_to_be32(sizeof(*header));
180-
header->tag = cpu_to_be16(TPM2_ST_NO_SESSIONS);
181-
header->return_code = cpu_to_be32(TPM2_RC_COMMAND_CODE |
182-
TSS2_RESMGR_TPM_RC_LAYER);
183-
return sizeof(*header);
184-
}
132+
if (bufsiz < TPM_HEADER_SIZE)
133+
return -EINVAL;
185134

186135
if (bufsiz > TPM_BUFSIZE)
187136
bufsiz = TPM_BUFSIZE;
@@ -196,7 +145,18 @@ static ssize_t tpm_try_transmit(struct tpm_chip *chip, struct tpm_space *space,
196145
return -E2BIG;
197146
}
198147

199-
rc = tpm2_prepare_space(chip, space, ordinal, buf);
148+
rc = tpm2_prepare_space(chip, space, buf, bufsiz);
149+
/*
150+
* If the command is not implemented by the TPM, synthesize a
151+
* response with a TPM2_RC_COMMAND_CODE return for user-space.
152+
*/
153+
if (rc == -EOPNOTSUPP) {
154+
header->length = cpu_to_be32(sizeof(*header));
155+
header->tag = cpu_to_be16(TPM2_ST_NO_SESSIONS);
156+
header->return_code = cpu_to_be32(TPM2_RC_COMMAND_CODE |
157+
TSS2_RESMGR_TPM_RC_LAYER);
158+
return sizeof(*header);
159+
}
200160
if (rc)
201161
return rc;
202162

@@ -252,7 +212,7 @@ static ssize_t tpm_try_transmit(struct tpm_chip *chip, struct tpm_space *space,
252212

253213
out_rc:
254214
if (!rc)
255-
rc = tpm2_commit_space(chip, space, ordinal, buf, &len);
215+
rc = tpm2_commit_space(chip, space, buf, &len);
256216

257217
return rc ? rc : len;
258218
}

drivers/char/tpm/tpm.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,7 @@ struct tpm_chip {
264264
#endif /* CONFIG_ACPI */
265265

266266
struct tpm_space work_space;
267+
u32 last_cc;
267268
u32 nr_commands;
268269
u32 *cc_attrs_tbl;
269270

@@ -577,10 +578,10 @@ int tpm2_find_cc(struct tpm_chip *chip, u32 cc);
577578
int tpm2_init_space(struct tpm_space *space);
578579
void tpm2_del_space(struct tpm_chip *chip, struct tpm_space *space);
579580
void tpm2_flush_space(struct tpm_chip *chip);
580-
int tpm2_prepare_space(struct tpm_chip *chip, struct tpm_space *space, u32 cc,
581-
u8 *cmd);
582-
int tpm2_commit_space(struct tpm_chip *chip, struct tpm_space *space,
583-
u32 cc, void *buf, size_t *bufsiz);
581+
int tpm2_prepare_space(struct tpm_chip *chip, struct tpm_space *space, u8 *cmd,
582+
size_t cmdsiz);
583+
int tpm2_commit_space(struct tpm_chip *chip, struct tpm_space *space, void *buf,
584+
size_t *bufsiz);
584585

585586
int tpm_bios_log_setup(struct tpm_chip *chip);
586587
void tpm_bios_log_teardown(struct tpm_chip *chip);

drivers/char/tpm/tpm2-space.c

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -264,14 +264,54 @@ static int tpm2_map_command(struct tpm_chip *chip, u32 cc, u8 *cmd)
264264
return 0;
265265
}
266266

267-
int tpm2_prepare_space(struct tpm_chip *chip, struct tpm_space *space, u32 cc,
268-
u8 *cmd)
267+
static int tpm_find_and_validate_cc(struct tpm_chip *chip,
268+
struct tpm_space *space,
269+
const void *cmd, size_t len)
270+
{
271+
const struct tpm_header *header = (const void *)cmd;
272+
int i;
273+
u32 cc;
274+
u32 attrs;
275+
unsigned int nr_handles;
276+
277+
if (len < TPM_HEADER_SIZE || !chip->nr_commands)
278+
return -EINVAL;
279+
280+
cc = be32_to_cpu(header->ordinal);
281+
282+
i = tpm2_find_cc(chip, cc);
283+
if (i < 0) {
284+
dev_dbg(&chip->dev, "0x%04X is an invalid command\n",
285+
cc);
286+
return -EOPNOTSUPP;
287+
}
288+
289+
attrs = chip->cc_attrs_tbl[i];
290+
nr_handles =
291+
4 * ((attrs >> TPM2_CC_ATTR_CHANDLES) & GENMASK(2, 0));
292+
if (len < TPM_HEADER_SIZE + 4 * nr_handles)
293+
goto err_len;
294+
295+
return cc;
296+
err_len:
297+
dev_dbg(&chip->dev, "%s: insufficient command length %zu", __func__,
298+
len);
299+
return -EINVAL;
300+
}
301+
302+
int tpm2_prepare_space(struct tpm_chip *chip, struct tpm_space *space, u8 *cmd,
303+
size_t cmdsiz)
269304
{
270305
int rc;
306+
int cc;
271307

272308
if (!space)
273309
return 0;
274310

311+
cc = tpm_find_and_validate_cc(chip, space, cmd, cmdsiz);
312+
if (cc < 0)
313+
return cc;
314+
275315
memcpy(&chip->work_space.context_tbl, &space->context_tbl,
276316
sizeof(space->context_tbl));
277317
memcpy(&chip->work_space.session_tbl, &space->session_tbl,
@@ -291,6 +331,7 @@ int tpm2_prepare_space(struct tpm_chip *chip, struct tpm_space *space, u32 cc,
291331
return rc;
292332
}
293333

334+
chip->last_cc = cc;
294335
return 0;
295336
}
296337

@@ -490,21 +531,21 @@ static int tpm2_save_space(struct tpm_chip *chip)
490531
}
491532

492533
int tpm2_commit_space(struct tpm_chip *chip, struct tpm_space *space,
493-
u32 cc, void *buf, size_t *bufsiz)
534+
void *buf, size_t *bufsiz)
494535
{
495536
struct tpm_header *header = buf;
496537
int rc;
497538

498539
if (!space)
499540
return 0;
500541

501-
rc = tpm2_map_response_header(chip, cc, buf, *bufsiz);
542+
rc = tpm2_map_response_header(chip, chip->last_cc, buf, *bufsiz);
502543
if (rc) {
503544
tpm2_flush_space(chip);
504545
goto out;
505546
}
506547

507-
rc = tpm2_map_response_body(chip, cc, buf, *bufsiz);
548+
rc = tpm2_map_response_body(chip, chip->last_cc, buf, *bufsiz);
508549
if (rc) {
509550
tpm2_flush_space(chip);
510551
goto out;

0 commit comments

Comments
 (0)