| .. | .. | 
|---|
|  | 1 | +// SPDX-License-Identifier: GPL-2.0-only | 
|---|
| 1 | 2 | /* | 
|---|
| 2 | 3 | * Copyright (C) 2014, 2015 Intel Corporation | 
|---|
| 3 | 4 | * | 
|---|
| .. | .. | 
|---|
| 8 | 9 | * | 
|---|
| 9 | 10 | * This file contains TPM2 protocol implementations of the commands | 
|---|
| 10 | 11 | * used by the kernel internally. | 
|---|
| 11 |  | - * | 
|---|
| 12 |  | - * This program is free software; you can redistribute it and/or | 
|---|
| 13 |  | - * modify it under the terms of the GNU General Public License | 
|---|
| 14 |  | - * as published by the Free Software Foundation; version 2 | 
|---|
| 15 |  | - * of the License. | 
|---|
| 16 | 12 | */ | 
|---|
| 17 | 13 |  | 
|---|
| 18 | 14 | #include "tpm.h" | 
|---|
| 19 | 15 | #include <crypto/hash_info.h> | 
|---|
| 20 |  | -#include <keys/trusted-type.h> | 
|---|
| 21 |  | - | 
|---|
| 22 |  | -enum tpm2_object_attributes { | 
|---|
| 23 |  | -	TPM2_OA_USER_WITH_AUTH		= BIT(6), | 
|---|
| 24 |  | -}; | 
|---|
| 25 |  | - | 
|---|
| 26 |  | -enum tpm2_session_attributes { | 
|---|
| 27 |  | -	TPM2_SA_CONTINUE_SESSION	= BIT(0), | 
|---|
| 28 |  | -}; | 
|---|
| 29 |  | - | 
|---|
| 30 |  | -struct tpm2_hash { | 
|---|
| 31 |  | -	unsigned int crypto_id; | 
|---|
| 32 |  | -	unsigned int tpm_id; | 
|---|
| 33 |  | -}; | 
|---|
| 34 | 16 |  | 
|---|
| 35 | 17 | static struct tpm2_hash tpm2_hash_map[] = { | 
|---|
| 36 |  | -	{HASH_ALGO_SHA1, TPM2_ALG_SHA1}, | 
|---|
| 37 |  | -	{HASH_ALGO_SHA256, TPM2_ALG_SHA256}, | 
|---|
| 38 |  | -	{HASH_ALGO_SHA384, TPM2_ALG_SHA384}, | 
|---|
| 39 |  | -	{HASH_ALGO_SHA512, TPM2_ALG_SHA512}, | 
|---|
| 40 |  | -	{HASH_ALGO_SM3_256, TPM2_ALG_SM3_256}, | 
|---|
|  | 18 | +	{HASH_ALGO_SHA1, TPM_ALG_SHA1}, | 
|---|
|  | 19 | +	{HASH_ALGO_SHA256, TPM_ALG_SHA256}, | 
|---|
|  | 20 | +	{HASH_ALGO_SHA384, TPM_ALG_SHA384}, | 
|---|
|  | 21 | +	{HASH_ALGO_SHA512, TPM_ALG_SHA512}, | 
|---|
|  | 22 | +	{HASH_ALGO_SM3_256, TPM_ALG_SM3_256}, | 
|---|
| 41 | 23 | }; | 
|---|
| 42 | 24 |  | 
|---|
| 43 |  | -/* | 
|---|
| 44 |  | - * Array with one entry per ordinal defining the maximum amount | 
|---|
| 45 |  | - * of time the chip could take to return the result. The values | 
|---|
| 46 |  | - * of the SHORT, MEDIUM, and LONG durations are taken from the | 
|---|
| 47 |  | - * PC Client Profile (PTP) specification. | 
|---|
| 48 |  | - * LONG_LONG is for commands that generates keys which empirically | 
|---|
| 49 |  | - * takes longer time on some systems. | 
|---|
|  | 25 | +int tpm2_get_timeouts(struct tpm_chip *chip) | 
|---|
|  | 26 | +{ | 
|---|
|  | 27 | +	/* Fixed timeouts for TPM2 */ | 
|---|
|  | 28 | +	chip->timeout_a = msecs_to_jiffies(TPM2_TIMEOUT_A); | 
|---|
|  | 29 | +	chip->timeout_b = msecs_to_jiffies(TPM2_TIMEOUT_B); | 
|---|
|  | 30 | +	chip->timeout_c = msecs_to_jiffies(TPM2_TIMEOUT_C); | 
|---|
|  | 31 | +	chip->timeout_d = msecs_to_jiffies(TPM2_TIMEOUT_D); | 
|---|
|  | 32 | + | 
|---|
|  | 33 | +	/* PTP spec timeouts */ | 
|---|
|  | 34 | +	chip->duration[TPM_SHORT] = msecs_to_jiffies(TPM2_DURATION_SHORT); | 
|---|
|  | 35 | +	chip->duration[TPM_MEDIUM] = msecs_to_jiffies(TPM2_DURATION_MEDIUM); | 
|---|
|  | 36 | +	chip->duration[TPM_LONG] = msecs_to_jiffies(TPM2_DURATION_LONG); | 
|---|
|  | 37 | + | 
|---|
|  | 38 | +	/* Key creation commands long timeouts */ | 
|---|
|  | 39 | +	chip->duration[TPM_LONG_LONG] = | 
|---|
|  | 40 | +		msecs_to_jiffies(TPM2_DURATION_LONG_LONG); | 
|---|
|  | 41 | + | 
|---|
|  | 42 | +	chip->flags |= TPM_CHIP_FLAG_HAVE_TIMEOUTS; | 
|---|
|  | 43 | + | 
|---|
|  | 44 | +	return 0; | 
|---|
|  | 45 | +} | 
|---|
|  | 46 | + | 
|---|
|  | 47 | +/** | 
|---|
|  | 48 | + * tpm2_ordinal_duration_index() - returns an index to the chip duration table | 
|---|
|  | 49 | + * @ordinal: TPM command ordinal. | 
|---|
|  | 50 | + * | 
|---|
|  | 51 | + * The function returns an index to the chip duration table | 
|---|
|  | 52 | + * (enum tpm_duration), that describes the maximum amount of | 
|---|
|  | 53 | + * time the chip could take to return the result for a  particular ordinal. | 
|---|
|  | 54 | + * | 
|---|
|  | 55 | + * The values of the MEDIUM, and LONG durations are taken | 
|---|
|  | 56 | + * from the PC Client Profile (PTP) specification (750, 2000 msec) | 
|---|
|  | 57 | + * | 
|---|
|  | 58 | + * LONG_LONG is for commands that generates keys which empirically takes | 
|---|
|  | 59 | + * a longer time on some systems. | 
|---|
|  | 60 | + * | 
|---|
|  | 61 | + * Return: | 
|---|
|  | 62 | + * * TPM_MEDIUM | 
|---|
|  | 63 | + * * TPM_LONG | 
|---|
|  | 64 | + * * TPM_LONG_LONG | 
|---|
|  | 65 | + * * TPM_UNDEFINED | 
|---|
| 50 | 66 | */ | 
|---|
| 51 |  | -static const u8 tpm2_ordinal_duration[TPM2_CC_LAST - TPM2_CC_FIRST + 1] = { | 
|---|
| 52 |  | -	TPM_UNDEFINED,		/* 11F */ | 
|---|
| 53 |  | -	TPM_UNDEFINED,		/* 120 */ | 
|---|
| 54 |  | -	TPM_LONG,		/* 121 */ | 
|---|
| 55 |  | -	TPM_UNDEFINED,		/* 122 */ | 
|---|
| 56 |  | -	TPM_UNDEFINED,		/* 123 */ | 
|---|
| 57 |  | -	TPM_UNDEFINED,		/* 124 */ | 
|---|
| 58 |  | -	TPM_UNDEFINED,		/* 125 */ | 
|---|
| 59 |  | -	TPM_UNDEFINED,		/* 126 */ | 
|---|
| 60 |  | -	TPM_UNDEFINED,		/* 127 */ | 
|---|
| 61 |  | -	TPM_UNDEFINED,		/* 128 */ | 
|---|
| 62 |  | -	TPM_LONG,		/* 129 */ | 
|---|
| 63 |  | -	TPM_UNDEFINED,		/* 12a */ | 
|---|
| 64 |  | -	TPM_UNDEFINED,		/* 12b */ | 
|---|
| 65 |  | -	TPM_UNDEFINED,		/* 12c */ | 
|---|
| 66 |  | -	TPM_UNDEFINED,		/* 12d */ | 
|---|
| 67 |  | -	TPM_UNDEFINED,		/* 12e */ | 
|---|
| 68 |  | -	TPM_UNDEFINED,		/* 12f */ | 
|---|
| 69 |  | -	TPM_UNDEFINED,		/* 130 */ | 
|---|
| 70 |  | -	TPM_LONG_LONG,		/* 131 */ | 
|---|
| 71 |  | -	TPM_UNDEFINED,		/* 132 */ | 
|---|
| 72 |  | -	TPM_UNDEFINED,		/* 133 */ | 
|---|
| 73 |  | -	TPM_UNDEFINED,		/* 134 */ | 
|---|
| 74 |  | -	TPM_UNDEFINED,		/* 135 */ | 
|---|
| 75 |  | -	TPM_UNDEFINED,		/* 136 */ | 
|---|
| 76 |  | -	TPM_UNDEFINED,		/* 137 */ | 
|---|
| 77 |  | -	TPM_UNDEFINED,		/* 138 */ | 
|---|
| 78 |  | -	TPM_UNDEFINED,		/* 139 */ | 
|---|
| 79 |  | -	TPM_UNDEFINED,		/* 13a */ | 
|---|
| 80 |  | -	TPM_UNDEFINED,		/* 13b */ | 
|---|
| 81 |  | -	TPM_UNDEFINED,		/* 13c */ | 
|---|
| 82 |  | -	TPM_UNDEFINED,		/* 13d */ | 
|---|
| 83 |  | -	TPM_MEDIUM,		/* 13e */ | 
|---|
| 84 |  | -	TPM_UNDEFINED,		/* 13f */ | 
|---|
| 85 |  | -	TPM_UNDEFINED,		/* 140 */ | 
|---|
| 86 |  | -	TPM_UNDEFINED,		/* 141 */ | 
|---|
| 87 |  | -	TPM_UNDEFINED,		/* 142 */ | 
|---|
| 88 |  | -	TPM_LONG,		/* 143 */ | 
|---|
| 89 |  | -	TPM_MEDIUM,		/* 144 */ | 
|---|
| 90 |  | -	TPM_UNDEFINED,		/* 145 */ | 
|---|
| 91 |  | -	TPM_UNDEFINED,		/* 146 */ | 
|---|
| 92 |  | -	TPM_UNDEFINED,		/* 147 */ | 
|---|
| 93 |  | -	TPM_UNDEFINED,		/* 148 */ | 
|---|
| 94 |  | -	TPM_UNDEFINED,		/* 149 */ | 
|---|
| 95 |  | -	TPM_UNDEFINED,		/* 14a */ | 
|---|
| 96 |  | -	TPM_UNDEFINED,		/* 14b */ | 
|---|
| 97 |  | -	TPM_UNDEFINED,		/* 14c */ | 
|---|
| 98 |  | -	TPM_UNDEFINED,		/* 14d */ | 
|---|
| 99 |  | -	TPM_LONG,		/* 14e */ | 
|---|
| 100 |  | -	TPM_UNDEFINED,		/* 14f */ | 
|---|
| 101 |  | -	TPM_UNDEFINED,		/* 150 */ | 
|---|
| 102 |  | -	TPM_UNDEFINED,		/* 151 */ | 
|---|
| 103 |  | -	TPM_UNDEFINED,		/* 152 */ | 
|---|
| 104 |  | -	TPM_LONG_LONG,		/* 153 */ | 
|---|
| 105 |  | -	TPM_UNDEFINED,		/* 154 */ | 
|---|
| 106 |  | -	TPM_UNDEFINED,		/* 155 */ | 
|---|
| 107 |  | -	TPM_UNDEFINED,		/* 156 */ | 
|---|
| 108 |  | -	TPM_UNDEFINED,		/* 157 */ | 
|---|
| 109 |  | -	TPM_UNDEFINED,		/* 158 */ | 
|---|
| 110 |  | -	TPM_UNDEFINED,		/* 159 */ | 
|---|
| 111 |  | -	TPM_UNDEFINED,		/* 15a */ | 
|---|
| 112 |  | -	TPM_UNDEFINED,		/* 15b */ | 
|---|
| 113 |  | -	TPM_MEDIUM,		/* 15c */ | 
|---|
| 114 |  | -	TPM_UNDEFINED,		/* 15d */ | 
|---|
| 115 |  | -	TPM_UNDEFINED,		/* 15e */ | 
|---|
| 116 |  | -	TPM_UNDEFINED,		/* 15f */ | 
|---|
| 117 |  | -	TPM_UNDEFINED,		/* 160 */ | 
|---|
| 118 |  | -	TPM_UNDEFINED,		/* 161 */ | 
|---|
| 119 |  | -	TPM_UNDEFINED,		/* 162 */ | 
|---|
| 120 |  | -	TPM_UNDEFINED,		/* 163 */ | 
|---|
| 121 |  | -	TPM_UNDEFINED,		/* 164 */ | 
|---|
| 122 |  | -	TPM_UNDEFINED,		/* 165 */ | 
|---|
| 123 |  | -	TPM_UNDEFINED,		/* 166 */ | 
|---|
| 124 |  | -	TPM_UNDEFINED,		/* 167 */ | 
|---|
| 125 |  | -	TPM_UNDEFINED,		/* 168 */ | 
|---|
| 126 |  | -	TPM_UNDEFINED,		/* 169 */ | 
|---|
| 127 |  | -	TPM_UNDEFINED,		/* 16a */ | 
|---|
| 128 |  | -	TPM_UNDEFINED,		/* 16b */ | 
|---|
| 129 |  | -	TPM_UNDEFINED,		/* 16c */ | 
|---|
| 130 |  | -	TPM_UNDEFINED,		/* 16d */ | 
|---|
| 131 |  | -	TPM_UNDEFINED,		/* 16e */ | 
|---|
| 132 |  | -	TPM_UNDEFINED,		/* 16f */ | 
|---|
| 133 |  | -	TPM_UNDEFINED,		/* 170 */ | 
|---|
| 134 |  | -	TPM_UNDEFINED,		/* 171 */ | 
|---|
| 135 |  | -	TPM_UNDEFINED,		/* 172 */ | 
|---|
| 136 |  | -	TPM_UNDEFINED,		/* 173 */ | 
|---|
| 137 |  | -	TPM_UNDEFINED,		/* 174 */ | 
|---|
| 138 |  | -	TPM_UNDEFINED,		/* 175 */ | 
|---|
| 139 |  | -	TPM_UNDEFINED,		/* 176 */ | 
|---|
| 140 |  | -	TPM_LONG,		/* 177 */ | 
|---|
| 141 |  | -	TPM_UNDEFINED,		/* 178 */ | 
|---|
| 142 |  | -	TPM_UNDEFINED,		/* 179 */ | 
|---|
| 143 |  | -	TPM_MEDIUM,		/* 17a */ | 
|---|
| 144 |  | -	TPM_LONG,		/* 17b */ | 
|---|
| 145 |  | -	TPM_UNDEFINED,		/* 17c */ | 
|---|
| 146 |  | -	TPM_UNDEFINED,		/* 17d */ | 
|---|
| 147 |  | -	TPM_UNDEFINED,		/* 17e */ | 
|---|
| 148 |  | -	TPM_UNDEFINED,		/* 17f */ | 
|---|
| 149 |  | -	TPM_UNDEFINED,		/* 180 */ | 
|---|
| 150 |  | -	TPM_UNDEFINED,		/* 181 */ | 
|---|
| 151 |  | -	TPM_MEDIUM,		/* 182 */ | 
|---|
| 152 |  | -	TPM_UNDEFINED,		/* 183 */ | 
|---|
| 153 |  | -	TPM_UNDEFINED,		/* 184 */ | 
|---|
| 154 |  | -	TPM_MEDIUM,		/* 185 */ | 
|---|
| 155 |  | -	TPM_MEDIUM,		/* 186 */ | 
|---|
| 156 |  | -	TPM_UNDEFINED,		/* 187 */ | 
|---|
| 157 |  | -	TPM_UNDEFINED,		/* 188 */ | 
|---|
| 158 |  | -	TPM_UNDEFINED,		/* 189 */ | 
|---|
| 159 |  | -	TPM_UNDEFINED,		/* 18a */ | 
|---|
| 160 |  | -	TPM_UNDEFINED,		/* 18b */ | 
|---|
| 161 |  | -	TPM_UNDEFINED,		/* 18c */ | 
|---|
| 162 |  | -	TPM_UNDEFINED,		/* 18d */ | 
|---|
| 163 |  | -	TPM_UNDEFINED,		/* 18e */ | 
|---|
| 164 |  | -	TPM_UNDEFINED		/* 18f */ | 
|---|
| 165 |  | -}; | 
|---|
|  | 67 | +static u8 tpm2_ordinal_duration_index(u32 ordinal) | 
|---|
|  | 68 | +{ | 
|---|
|  | 69 | +	switch (ordinal) { | 
|---|
|  | 70 | +	/* Startup */ | 
|---|
|  | 71 | +	case TPM2_CC_STARTUP:                 /* 144 */ | 
|---|
|  | 72 | +		return TPM_MEDIUM; | 
|---|
|  | 73 | + | 
|---|
|  | 74 | +	case TPM2_CC_SELF_TEST:               /* 143 */ | 
|---|
|  | 75 | +		return TPM_LONG; | 
|---|
|  | 76 | + | 
|---|
|  | 77 | +	case TPM2_CC_GET_RANDOM:              /* 17B */ | 
|---|
|  | 78 | +		return TPM_LONG; | 
|---|
|  | 79 | + | 
|---|
|  | 80 | +	case TPM2_CC_SEQUENCE_UPDATE:         /* 15C */ | 
|---|
|  | 81 | +		return TPM_MEDIUM; | 
|---|
|  | 82 | +	case TPM2_CC_SEQUENCE_COMPLETE:       /* 13E */ | 
|---|
|  | 83 | +		return TPM_MEDIUM; | 
|---|
|  | 84 | +	case TPM2_CC_EVENT_SEQUENCE_COMPLETE: /* 185 */ | 
|---|
|  | 85 | +		return TPM_MEDIUM; | 
|---|
|  | 86 | +	case TPM2_CC_HASH_SEQUENCE_START:     /* 186 */ | 
|---|
|  | 87 | +		return TPM_MEDIUM; | 
|---|
|  | 88 | + | 
|---|
|  | 89 | +	case TPM2_CC_VERIFY_SIGNATURE:        /* 177 */ | 
|---|
|  | 90 | +		return TPM_LONG; | 
|---|
|  | 91 | + | 
|---|
|  | 92 | +	case TPM2_CC_PCR_EXTEND:              /* 182 */ | 
|---|
|  | 93 | +		return TPM_MEDIUM; | 
|---|
|  | 94 | + | 
|---|
|  | 95 | +	case TPM2_CC_HIERARCHY_CONTROL:       /* 121 */ | 
|---|
|  | 96 | +		return TPM_LONG; | 
|---|
|  | 97 | +	case TPM2_CC_HIERARCHY_CHANGE_AUTH:   /* 129 */ | 
|---|
|  | 98 | +		return TPM_LONG; | 
|---|
|  | 99 | + | 
|---|
|  | 100 | +	case TPM2_CC_GET_CAPABILITY:          /* 17A */ | 
|---|
|  | 101 | +		return TPM_MEDIUM; | 
|---|
|  | 102 | + | 
|---|
|  | 103 | +	case TPM2_CC_NV_READ:                 /* 14E */ | 
|---|
|  | 104 | +		return TPM_LONG; | 
|---|
|  | 105 | + | 
|---|
|  | 106 | +	case TPM2_CC_CREATE_PRIMARY:          /* 131 */ | 
|---|
|  | 107 | +		return TPM_LONG_LONG; | 
|---|
|  | 108 | +	case TPM2_CC_CREATE:                  /* 153 */ | 
|---|
|  | 109 | +		return TPM_LONG_LONG; | 
|---|
|  | 110 | +	case TPM2_CC_CREATE_LOADED:           /* 191 */ | 
|---|
|  | 111 | +		return TPM_LONG_LONG; | 
|---|
|  | 112 | + | 
|---|
|  | 113 | +	default: | 
|---|
|  | 114 | +		return TPM_UNDEFINED; | 
|---|
|  | 115 | +	} | 
|---|
|  | 116 | +} | 
|---|
|  | 117 | + | 
|---|
|  | 118 | +/** | 
|---|
|  | 119 | + * tpm2_calc_ordinal_duration() - calculate the maximum command duration | 
|---|
|  | 120 | + * @chip:    TPM chip to use. | 
|---|
|  | 121 | + * @ordinal: TPM command ordinal. | 
|---|
|  | 122 | + * | 
|---|
|  | 123 | + * The function returns the maximum amount of time the chip could take | 
|---|
|  | 124 | + * to return the result for a particular ordinal in jiffies. | 
|---|
|  | 125 | + * | 
|---|
|  | 126 | + * Return: A maximal duration time for an ordinal in jiffies. | 
|---|
|  | 127 | + */ | 
|---|
|  | 128 | +unsigned long tpm2_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal) | 
|---|
|  | 129 | +{ | 
|---|
|  | 130 | +	unsigned int index; | 
|---|
|  | 131 | + | 
|---|
|  | 132 | +	index = tpm2_ordinal_duration_index(ordinal); | 
|---|
|  | 133 | + | 
|---|
|  | 134 | +	if (index != TPM_UNDEFINED) | 
|---|
|  | 135 | +		return chip->duration[index]; | 
|---|
|  | 136 | +	else | 
|---|
|  | 137 | +		return msecs_to_jiffies(TPM2_DURATION_DEFAULT); | 
|---|
|  | 138 | +} | 
|---|
|  | 139 | + | 
|---|
| 166 | 140 |  | 
|---|
| 167 | 141 | struct tpm2_pcr_read_out { | 
|---|
| 168 | 142 | __be32	update_cnt; | 
|---|
| .. | .. | 
|---|
| 179 | 153 | * tpm2_pcr_read() - read a PCR value | 
|---|
| 180 | 154 | * @chip:	TPM chip to use. | 
|---|
| 181 | 155 | * @pcr_idx:	index of the PCR to read. | 
|---|
| 182 |  | - * @res_buf:	buffer to store the resulting hash. | 
|---|
|  | 156 | + * @digest:	PCR bank and buffer current PCR value is written to. | 
|---|
|  | 157 | + * @digest_size_ptr:	pointer to variable that stores the digest size. | 
|---|
| 183 | 158 | * | 
|---|
| 184 | 159 | * Return: Same as with tpm_transmit_cmd. | 
|---|
| 185 | 160 | */ | 
|---|
| 186 |  | -int tpm2_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf) | 
|---|
|  | 161 | +int tpm2_pcr_read(struct tpm_chip *chip, u32 pcr_idx, | 
|---|
|  | 162 | +		  struct tpm_digest *digest, u16 *digest_size_ptr) | 
|---|
| 187 | 163 | { | 
|---|
|  | 164 | +	int i; | 
|---|
| 188 | 165 | int rc; | 
|---|
| 189 | 166 | struct tpm_buf buf; | 
|---|
| 190 | 167 | struct tpm2_pcr_read_out *out; | 
|---|
| 191 | 168 | u8 pcr_select[TPM2_PCR_SELECT_MIN] = {0}; | 
|---|
|  | 169 | +	u16 digest_size; | 
|---|
|  | 170 | +	u16 expected_digest_size = 0; | 
|---|
| 192 | 171 |  | 
|---|
| 193 | 172 | if (pcr_idx >= TPM2_PLATFORM_PCR) | 
|---|
| 194 | 173 | return -EINVAL; | 
|---|
|  | 174 | + | 
|---|
|  | 175 | +	if (!digest_size_ptr) { | 
|---|
|  | 176 | +		for (i = 0; i < chip->nr_allocated_banks && | 
|---|
|  | 177 | +		     chip->allocated_banks[i].alg_id != digest->alg_id; i++) | 
|---|
|  | 178 | +			; | 
|---|
|  | 179 | + | 
|---|
|  | 180 | +		if (i == chip->nr_allocated_banks) | 
|---|
|  | 181 | +			return -EINVAL; | 
|---|
|  | 182 | + | 
|---|
|  | 183 | +		expected_digest_size = chip->allocated_banks[i].digest_size; | 
|---|
|  | 184 | +	} | 
|---|
| 195 | 185 |  | 
|---|
| 196 | 186 | rc = tpm_buf_init(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_PCR_READ); | 
|---|
| 197 | 187 | if (rc) | 
|---|
| .. | .. | 
|---|
| 200 | 190 | pcr_select[pcr_idx >> 3] = 1 << (pcr_idx & 0x7); | 
|---|
| 201 | 191 |  | 
|---|
| 202 | 192 | tpm_buf_append_u32(&buf, 1); | 
|---|
| 203 |  | -	tpm_buf_append_u16(&buf, TPM2_ALG_SHA1); | 
|---|
|  | 193 | +	tpm_buf_append_u16(&buf, digest->alg_id); | 
|---|
| 204 | 194 | tpm_buf_append_u8(&buf, TPM2_PCR_SELECT_MIN); | 
|---|
| 205 | 195 | tpm_buf_append(&buf, (const unsigned char *)pcr_select, | 
|---|
| 206 | 196 | sizeof(pcr_select)); | 
|---|
| 207 | 197 |  | 
|---|
| 208 |  | -	rc = tpm_transmit_cmd(chip, NULL, buf.data, PAGE_SIZE, 0, 0, | 
|---|
| 209 |  | -			res_buf ? "attempting to read a pcr value" : NULL); | 
|---|
| 210 |  | -	if (rc == 0 && res_buf) { | 
|---|
| 211 |  | -		out = (struct tpm2_pcr_read_out *)&buf.data[TPM_HEADER_SIZE]; | 
|---|
| 212 |  | -		memcpy(res_buf, out->digest, SHA1_DIGEST_SIZE); | 
|---|
|  | 198 | +	rc = tpm_transmit_cmd(chip, &buf, 0, "attempting to read a pcr value"); | 
|---|
|  | 199 | +	if (rc) | 
|---|
|  | 200 | +		goto out; | 
|---|
|  | 201 | + | 
|---|
|  | 202 | +	out = (struct tpm2_pcr_read_out *)&buf.data[TPM_HEADER_SIZE]; | 
|---|
|  | 203 | +	digest_size = be16_to_cpu(out->digest_size); | 
|---|
|  | 204 | +	if (digest_size > sizeof(digest->digest) || | 
|---|
|  | 205 | +	    (!digest_size_ptr && digest_size != expected_digest_size)) { | 
|---|
|  | 206 | +		rc = -EINVAL; | 
|---|
|  | 207 | +		goto out; | 
|---|
| 213 | 208 | } | 
|---|
| 214 | 209 |  | 
|---|
|  | 210 | +	if (digest_size_ptr) | 
|---|
|  | 211 | +		*digest_size_ptr = digest_size; | 
|---|
|  | 212 | + | 
|---|
|  | 213 | +	memcpy(digest->digest, out->digest, digest_size); | 
|---|
|  | 214 | +out: | 
|---|
| 215 | 215 | tpm_buf_destroy(&buf); | 
|---|
| 216 | 216 | return rc; | 
|---|
| 217 | 217 | } | 
|---|
| .. | .. | 
|---|
| 228 | 228 | * | 
|---|
| 229 | 229 | * @chip:	TPM chip to use. | 
|---|
| 230 | 230 | * @pcr_idx:	index of the PCR. | 
|---|
| 231 |  | - * @count:	number of digests passed. | 
|---|
| 232 | 231 | * @digests:	list of pcr banks and corresponding digest values to extend. | 
|---|
| 233 | 232 | * | 
|---|
| 234 | 233 | * Return: Same as with tpm_transmit_cmd. | 
|---|
| 235 | 234 | */ | 
|---|
| 236 |  | -int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx, u32 count, | 
|---|
| 237 |  | -		    struct tpm2_digest *digests) | 
|---|
|  | 235 | +int tpm2_pcr_extend(struct tpm_chip *chip, u32 pcr_idx, | 
|---|
|  | 236 | +		    struct tpm_digest *digests) | 
|---|
| 238 | 237 | { | 
|---|
| 239 | 238 | struct tpm_buf buf; | 
|---|
| 240 | 239 | struct tpm2_null_auth_area auth_area; | 
|---|
| 241 | 240 | int rc; | 
|---|
| 242 | 241 | int i; | 
|---|
| 243 |  | -	int j; | 
|---|
| 244 |  | - | 
|---|
| 245 |  | -	if (count > ARRAY_SIZE(chip->active_banks)) | 
|---|
| 246 |  | -		return -EINVAL; | 
|---|
| 247 | 242 |  | 
|---|
| 248 | 243 | rc = tpm_buf_init(&buf, TPM2_ST_SESSIONS, TPM2_CC_PCR_EXTEND); | 
|---|
| 249 | 244 | if (rc) | 
|---|
| .. | .. | 
|---|
| 259 | 254 | tpm_buf_append_u32(&buf, sizeof(struct tpm2_null_auth_area)); | 
|---|
| 260 | 255 | tpm_buf_append(&buf, (const unsigned char *)&auth_area, | 
|---|
| 261 | 256 | sizeof(auth_area)); | 
|---|
| 262 |  | -	tpm_buf_append_u32(&buf, count); | 
|---|
|  | 257 | +	tpm_buf_append_u32(&buf, chip->nr_allocated_banks); | 
|---|
| 263 | 258 |  | 
|---|
| 264 |  | -	for (i = 0; i < count; i++) { | 
|---|
| 265 |  | -		for (j = 0; j < ARRAY_SIZE(tpm2_hash_map); j++) { | 
|---|
| 266 |  | -			if (digests[i].alg_id != tpm2_hash_map[j].tpm_id) | 
|---|
| 267 |  | -				continue; | 
|---|
| 268 |  | -			tpm_buf_append_u16(&buf, digests[i].alg_id); | 
|---|
| 269 |  | -			tpm_buf_append(&buf, (const unsigned char | 
|---|
| 270 |  | -					      *)&digests[i].digest, | 
|---|
| 271 |  | -			       hash_digest_size[tpm2_hash_map[j].crypto_id]); | 
|---|
| 272 |  | -		} | 
|---|
|  | 259 | +	for (i = 0; i < chip->nr_allocated_banks; i++) { | 
|---|
|  | 260 | +		tpm_buf_append_u16(&buf, digests[i].alg_id); | 
|---|
|  | 261 | +		tpm_buf_append(&buf, (const unsigned char *)&digests[i].digest, | 
|---|
|  | 262 | +			       chip->allocated_banks[i].digest_size); | 
|---|
| 273 | 263 | } | 
|---|
| 274 | 264 |  | 
|---|
| 275 |  | -	rc = tpm_transmit_cmd(chip, NULL, buf.data, PAGE_SIZE, 0, 0, | 
|---|
| 276 |  | -			      "attempting extend a PCR value"); | 
|---|
|  | 265 | +	rc = tpm_transmit_cmd(chip, &buf, 0, "attempting extend a PCR value"); | 
|---|
| 277 | 266 |  | 
|---|
| 278 | 267 | tpm_buf_destroy(&buf); | 
|---|
| 279 | 268 |  | 
|---|
| 280 | 269 | return rc; | 
|---|
| 281 | 270 | } | 
|---|
| 282 |  | - | 
|---|
| 283 | 271 |  | 
|---|
| 284 | 272 | struct tpm2_get_random_out { | 
|---|
| 285 | 273 | __be16 size; | 
|---|
| .. | .. | 
|---|
| 295 | 283 | * | 
|---|
| 296 | 284 | * Return: | 
|---|
| 297 | 285 | *   size of the buffer on success, | 
|---|
| 298 |  | - *   -errno otherwise | 
|---|
|  | 286 | + *   -errno otherwise (positive TPM return codes are masked to -EIO) | 
|---|
| 299 | 287 | */ | 
|---|
| 300 | 288 | int tpm2_get_random(struct tpm_chip *chip, u8 *dest, size_t max) | 
|---|
| 301 | 289 | { | 
|---|
| .. | .. | 
|---|
| 318 | 306 | do { | 
|---|
| 319 | 307 | tpm_buf_reset(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_GET_RANDOM); | 
|---|
| 320 | 308 | tpm_buf_append_u16(&buf, num_bytes); | 
|---|
| 321 |  | -		err = tpm_transmit_cmd(chip, NULL, buf.data, PAGE_SIZE, | 
|---|
|  | 309 | +		err = tpm_transmit_cmd(chip, &buf, | 
|---|
| 322 | 310 | offsetof(struct tpm2_get_random_out, | 
|---|
| 323 | 311 | buffer), | 
|---|
| 324 |  | -				       0, "attempting get random"); | 
|---|
| 325 |  | -		if (err) | 
|---|
|  | 312 | +				       "attempting get random"); | 
|---|
|  | 313 | +		if (err) { | 
|---|
|  | 314 | +			if (err > 0) | 
|---|
|  | 315 | +				err = -EIO; | 
|---|
| 326 | 316 | goto out; | 
|---|
|  | 317 | +		} | 
|---|
| 327 | 318 |  | 
|---|
| 328 | 319 | out = (struct tpm2_get_random_out *) | 
|---|
| 329 | 320 | &buf.data[TPM_HEADER_SIZE]; | 
|---|
| .. | .. | 
|---|
| 350 | 341 | } | 
|---|
| 351 | 342 |  | 
|---|
| 352 | 343 | /** | 
|---|
| 353 |  | - * tpm2_flush_context_cmd() - execute a TPM2_FlushContext command | 
|---|
| 354 |  | - * @chip: TPM chip to use | 
|---|
| 355 |  | - * @payload: the key data in clear and encrypted form | 
|---|
| 356 |  | - * @options: authentication values and other options | 
|---|
| 357 |  | - * | 
|---|
| 358 |  | - * Return: same as with tpm_transmit_cmd | 
|---|
|  | 344 | + * tpm2_flush_context() - execute a TPM2_FlushContext command | 
|---|
|  | 345 | + * @chip:	TPM chip to use | 
|---|
|  | 346 | + * @handle:	context handle | 
|---|
| 359 | 347 | */ | 
|---|
| 360 |  | -void tpm2_flush_context_cmd(struct tpm_chip *chip, u32 handle, | 
|---|
| 361 |  | -			    unsigned int flags) | 
|---|
|  | 348 | +void tpm2_flush_context(struct tpm_chip *chip, u32 handle) | 
|---|
| 362 | 349 | { | 
|---|
| 363 | 350 | struct tpm_buf buf; | 
|---|
| 364 | 351 | int rc; | 
|---|
| .. | .. | 
|---|
| 372 | 359 |  | 
|---|
| 373 | 360 | tpm_buf_append_u32(&buf, handle); | 
|---|
| 374 | 361 |  | 
|---|
| 375 |  | -	(void) tpm_transmit_cmd(chip, NULL, buf.data, PAGE_SIZE, 0, flags, | 
|---|
| 376 |  | -				"flushing context"); | 
|---|
| 377 |  | - | 
|---|
|  | 362 | +	tpm_transmit_cmd(chip, &buf, 0, "flushing context"); | 
|---|
| 378 | 363 | tpm_buf_destroy(&buf); | 
|---|
| 379 | 364 | } | 
|---|
| 380 |  | - | 
|---|
| 381 |  | -/** | 
|---|
| 382 |  | - * tpm_buf_append_auth() - append TPMS_AUTH_COMMAND to the buffer. | 
|---|
| 383 |  | - * | 
|---|
| 384 |  | - * @buf: an allocated tpm_buf instance | 
|---|
| 385 |  | - * @session_handle: session handle | 
|---|
| 386 |  | - * @nonce: the session nonce, may be NULL if not used | 
|---|
| 387 |  | - * @nonce_len: the session nonce length, may be 0 if not used | 
|---|
| 388 |  | - * @attributes: the session attributes | 
|---|
| 389 |  | - * @hmac: the session HMAC or password, may be NULL if not used | 
|---|
| 390 |  | - * @hmac_len: the session HMAC or password length, maybe 0 if not used | 
|---|
| 391 |  | - */ | 
|---|
| 392 |  | -static void tpm2_buf_append_auth(struct tpm_buf *buf, u32 session_handle, | 
|---|
| 393 |  | -				 const u8 *nonce, u16 nonce_len, | 
|---|
| 394 |  | -				 u8 attributes, | 
|---|
| 395 |  | -				 const u8 *hmac, u16 hmac_len) | 
|---|
| 396 |  | -{ | 
|---|
| 397 |  | -	tpm_buf_append_u32(buf, 9 + nonce_len + hmac_len); | 
|---|
| 398 |  | -	tpm_buf_append_u32(buf, session_handle); | 
|---|
| 399 |  | -	tpm_buf_append_u16(buf, nonce_len); | 
|---|
| 400 |  | - | 
|---|
| 401 |  | -	if (nonce && nonce_len) | 
|---|
| 402 |  | -		tpm_buf_append(buf, nonce, nonce_len); | 
|---|
| 403 |  | - | 
|---|
| 404 |  | -	tpm_buf_append_u8(buf, attributes); | 
|---|
| 405 |  | -	tpm_buf_append_u16(buf, hmac_len); | 
|---|
| 406 |  | - | 
|---|
| 407 |  | -	if (hmac && hmac_len) | 
|---|
| 408 |  | -		tpm_buf_append(buf, hmac, hmac_len); | 
|---|
| 409 |  | -} | 
|---|
| 410 |  | - | 
|---|
| 411 |  | -/** | 
|---|
| 412 |  | - * tpm2_seal_trusted() - seal the payload of a trusted key | 
|---|
| 413 |  | - * | 
|---|
| 414 |  | - * @chip: TPM chip to use | 
|---|
| 415 |  | - * @payload: the key data in clear and encrypted form | 
|---|
| 416 |  | - * @options: authentication values and other options | 
|---|
| 417 |  | - * | 
|---|
| 418 |  | - * Return: < 0 on error and 0 on success. | 
|---|
| 419 |  | - */ | 
|---|
| 420 |  | -int tpm2_seal_trusted(struct tpm_chip *chip, | 
|---|
| 421 |  | -		      struct trusted_key_payload *payload, | 
|---|
| 422 |  | -		      struct trusted_key_options *options) | 
|---|
| 423 |  | -{ | 
|---|
| 424 |  | -	unsigned int blob_len; | 
|---|
| 425 |  | -	struct tpm_buf buf; | 
|---|
| 426 |  | -	u32 hash; | 
|---|
| 427 |  | -	int i; | 
|---|
| 428 |  | -	int rc; | 
|---|
| 429 |  | - | 
|---|
| 430 |  | -	for (i = 0; i < ARRAY_SIZE(tpm2_hash_map); i++) { | 
|---|
| 431 |  | -		if (options->hash == tpm2_hash_map[i].crypto_id) { | 
|---|
| 432 |  | -			hash = tpm2_hash_map[i].tpm_id; | 
|---|
| 433 |  | -			break; | 
|---|
| 434 |  | -		} | 
|---|
| 435 |  | -	} | 
|---|
| 436 |  | - | 
|---|
| 437 |  | -	if (i == ARRAY_SIZE(tpm2_hash_map)) | 
|---|
| 438 |  | -		return -EINVAL; | 
|---|
| 439 |  | - | 
|---|
| 440 |  | -	rc = tpm_buf_init(&buf, TPM2_ST_SESSIONS, TPM2_CC_CREATE); | 
|---|
| 441 |  | -	if (rc) | 
|---|
| 442 |  | -		return rc; | 
|---|
| 443 |  | - | 
|---|
| 444 |  | -	tpm_buf_append_u32(&buf, options->keyhandle); | 
|---|
| 445 |  | -	tpm2_buf_append_auth(&buf, TPM2_RS_PW, | 
|---|
| 446 |  | -			     NULL /* nonce */, 0, | 
|---|
| 447 |  | -			     0 /* session_attributes */, | 
|---|
| 448 |  | -			     options->keyauth /* hmac */, | 
|---|
| 449 |  | -			     TPM_DIGEST_SIZE); | 
|---|
| 450 |  | - | 
|---|
| 451 |  | -	/* sensitive */ | 
|---|
| 452 |  | -	tpm_buf_append_u16(&buf, 4 + TPM_DIGEST_SIZE + payload->key_len + 1); | 
|---|
| 453 |  | - | 
|---|
| 454 |  | -	tpm_buf_append_u16(&buf, TPM_DIGEST_SIZE); | 
|---|
| 455 |  | -	tpm_buf_append(&buf, options->blobauth, TPM_DIGEST_SIZE); | 
|---|
| 456 |  | -	tpm_buf_append_u16(&buf, payload->key_len + 1); | 
|---|
| 457 |  | -	tpm_buf_append(&buf, payload->key, payload->key_len); | 
|---|
| 458 |  | -	tpm_buf_append_u8(&buf, payload->migratable); | 
|---|
| 459 |  | - | 
|---|
| 460 |  | -	/* public */ | 
|---|
| 461 |  | -	tpm_buf_append_u16(&buf, 14 + options->policydigest_len); | 
|---|
| 462 |  | -	tpm_buf_append_u16(&buf, TPM2_ALG_KEYEDHASH); | 
|---|
| 463 |  | -	tpm_buf_append_u16(&buf, hash); | 
|---|
| 464 |  | - | 
|---|
| 465 |  | -	/* policy */ | 
|---|
| 466 |  | -	if (options->policydigest_len) { | 
|---|
| 467 |  | -		tpm_buf_append_u32(&buf, 0); | 
|---|
| 468 |  | -		tpm_buf_append_u16(&buf, options->policydigest_len); | 
|---|
| 469 |  | -		tpm_buf_append(&buf, options->policydigest, | 
|---|
| 470 |  | -			       options->policydigest_len); | 
|---|
| 471 |  | -	} else { | 
|---|
| 472 |  | -		tpm_buf_append_u32(&buf, TPM2_OA_USER_WITH_AUTH); | 
|---|
| 473 |  | -		tpm_buf_append_u16(&buf, 0); | 
|---|
| 474 |  | -	} | 
|---|
| 475 |  | - | 
|---|
| 476 |  | -	/* public parameters */ | 
|---|
| 477 |  | -	tpm_buf_append_u16(&buf, TPM2_ALG_NULL); | 
|---|
| 478 |  | -	tpm_buf_append_u16(&buf, 0); | 
|---|
| 479 |  | - | 
|---|
| 480 |  | -	/* outside info */ | 
|---|
| 481 |  | -	tpm_buf_append_u16(&buf, 0); | 
|---|
| 482 |  | - | 
|---|
| 483 |  | -	/* creation PCR */ | 
|---|
| 484 |  | -	tpm_buf_append_u32(&buf, 0); | 
|---|
| 485 |  | - | 
|---|
| 486 |  | -	if (buf.flags & TPM_BUF_OVERFLOW) { | 
|---|
| 487 |  | -		rc = -E2BIG; | 
|---|
| 488 |  | -		goto out; | 
|---|
| 489 |  | -	} | 
|---|
| 490 |  | - | 
|---|
| 491 |  | -	rc = tpm_transmit_cmd(chip, NULL, buf.data, PAGE_SIZE, 4, 0, | 
|---|
| 492 |  | -			      "sealing data"); | 
|---|
| 493 |  | -	if (rc) | 
|---|
| 494 |  | -		goto out; | 
|---|
| 495 |  | - | 
|---|
| 496 |  | -	blob_len = be32_to_cpup((__be32 *) &buf.data[TPM_HEADER_SIZE]); | 
|---|
| 497 |  | -	if (blob_len > MAX_BLOB_SIZE) { | 
|---|
| 498 |  | -		rc = -E2BIG; | 
|---|
| 499 |  | -		goto out; | 
|---|
| 500 |  | -	} | 
|---|
| 501 |  | -	if (tpm_buf_length(&buf) < TPM_HEADER_SIZE + 4 + blob_len) { | 
|---|
| 502 |  | -		rc = -EFAULT; | 
|---|
| 503 |  | -		goto out; | 
|---|
| 504 |  | -	} | 
|---|
| 505 |  | - | 
|---|
| 506 |  | -	memcpy(payload->blob, &buf.data[TPM_HEADER_SIZE + 4], blob_len); | 
|---|
| 507 |  | -	payload->blob_len = blob_len; | 
|---|
| 508 |  | - | 
|---|
| 509 |  | -out: | 
|---|
| 510 |  | -	tpm_buf_destroy(&buf); | 
|---|
| 511 |  | - | 
|---|
| 512 |  | -	if (rc > 0) { | 
|---|
| 513 |  | -		if (tpm2_rc_value(rc) == TPM2_RC_HASH) | 
|---|
| 514 |  | -			rc = -EINVAL; | 
|---|
| 515 |  | -		else | 
|---|
| 516 |  | -			rc = -EPERM; | 
|---|
| 517 |  | -	} | 
|---|
| 518 |  | - | 
|---|
| 519 |  | -	return rc; | 
|---|
| 520 |  | -} | 
|---|
| 521 |  | - | 
|---|
| 522 |  | -/** | 
|---|
| 523 |  | - * tpm2_load_cmd() - execute a TPM2_Load command | 
|---|
| 524 |  | - * | 
|---|
| 525 |  | - * @chip: TPM chip to use | 
|---|
| 526 |  | - * @payload: the key data in clear and encrypted form | 
|---|
| 527 |  | - * @options: authentication values and other options | 
|---|
| 528 |  | - * @blob_handle: returned blob handle | 
|---|
| 529 |  | - * @flags: tpm transmit flags | 
|---|
| 530 |  | - * | 
|---|
| 531 |  | - * Return: 0 on success. | 
|---|
| 532 |  | - *        -E2BIG on wrong payload size. | 
|---|
| 533 |  | - *        -EPERM on tpm error status. | 
|---|
| 534 |  | - *        < 0 error from tpm_transmit_cmd. | 
|---|
| 535 |  | - */ | 
|---|
| 536 |  | -static int tpm2_load_cmd(struct tpm_chip *chip, | 
|---|
| 537 |  | -			 struct trusted_key_payload *payload, | 
|---|
| 538 |  | -			 struct trusted_key_options *options, | 
|---|
| 539 |  | -			 u32 *blob_handle, unsigned int flags) | 
|---|
| 540 |  | -{ | 
|---|
| 541 |  | -	struct tpm_buf buf; | 
|---|
| 542 |  | -	unsigned int private_len; | 
|---|
| 543 |  | -	unsigned int public_len; | 
|---|
| 544 |  | -	unsigned int blob_len; | 
|---|
| 545 |  | -	int rc; | 
|---|
| 546 |  | - | 
|---|
| 547 |  | -	private_len = be16_to_cpup((__be16 *) &payload->blob[0]); | 
|---|
| 548 |  | -	if (private_len > (payload->blob_len - 2)) | 
|---|
| 549 |  | -		return -E2BIG; | 
|---|
| 550 |  | - | 
|---|
| 551 |  | -	public_len = be16_to_cpup((__be16 *) &payload->blob[2 + private_len]); | 
|---|
| 552 |  | -	blob_len = private_len + public_len + 4; | 
|---|
| 553 |  | -	if (blob_len > payload->blob_len) | 
|---|
| 554 |  | -		return -E2BIG; | 
|---|
| 555 |  | - | 
|---|
| 556 |  | -	rc = tpm_buf_init(&buf, TPM2_ST_SESSIONS, TPM2_CC_LOAD); | 
|---|
| 557 |  | -	if (rc) | 
|---|
| 558 |  | -		return rc; | 
|---|
| 559 |  | - | 
|---|
| 560 |  | -	tpm_buf_append_u32(&buf, options->keyhandle); | 
|---|
| 561 |  | -	tpm2_buf_append_auth(&buf, TPM2_RS_PW, | 
|---|
| 562 |  | -			     NULL /* nonce */, 0, | 
|---|
| 563 |  | -			     0 /* session_attributes */, | 
|---|
| 564 |  | -			     options->keyauth /* hmac */, | 
|---|
| 565 |  | -			     TPM_DIGEST_SIZE); | 
|---|
| 566 |  | - | 
|---|
| 567 |  | -	tpm_buf_append(&buf, payload->blob, blob_len); | 
|---|
| 568 |  | - | 
|---|
| 569 |  | -	if (buf.flags & TPM_BUF_OVERFLOW) { | 
|---|
| 570 |  | -		rc = -E2BIG; | 
|---|
| 571 |  | -		goto out; | 
|---|
| 572 |  | -	} | 
|---|
| 573 |  | - | 
|---|
| 574 |  | -	rc = tpm_transmit_cmd(chip, NULL, buf.data, PAGE_SIZE, 4, flags, | 
|---|
| 575 |  | -			      "loading blob"); | 
|---|
| 576 |  | -	if (!rc) | 
|---|
| 577 |  | -		*blob_handle = be32_to_cpup( | 
|---|
| 578 |  | -			(__be32 *) &buf.data[TPM_HEADER_SIZE]); | 
|---|
| 579 |  | - | 
|---|
| 580 |  | -out: | 
|---|
| 581 |  | -	tpm_buf_destroy(&buf); | 
|---|
| 582 |  | - | 
|---|
| 583 |  | -	if (rc > 0) | 
|---|
| 584 |  | -		rc = -EPERM; | 
|---|
| 585 |  | - | 
|---|
| 586 |  | -	return rc; | 
|---|
| 587 |  | -} | 
|---|
| 588 |  | - | 
|---|
| 589 |  | -/** | 
|---|
| 590 |  | - * tpm2_unseal_cmd() - execute a TPM2_Unload command | 
|---|
| 591 |  | - * | 
|---|
| 592 |  | - * @chip: TPM chip to use | 
|---|
| 593 |  | - * @payload: the key data in clear and encrypted form | 
|---|
| 594 |  | - * @options: authentication values and other options | 
|---|
| 595 |  | - * @blob_handle: blob handle | 
|---|
| 596 |  | - * @flags: tpm_transmit_cmd flags | 
|---|
| 597 |  | - * | 
|---|
| 598 |  | - * Return: 0 on success | 
|---|
| 599 |  | - *         -EPERM on tpm error status | 
|---|
| 600 |  | - *         < 0 error from tpm_transmit_cmd | 
|---|
| 601 |  | - */ | 
|---|
| 602 |  | -static int tpm2_unseal_cmd(struct tpm_chip *chip, | 
|---|
| 603 |  | -			   struct trusted_key_payload *payload, | 
|---|
| 604 |  | -			   struct trusted_key_options *options, | 
|---|
| 605 |  | -			   u32 blob_handle, unsigned int flags) | 
|---|
| 606 |  | -{ | 
|---|
| 607 |  | -	struct tpm_buf buf; | 
|---|
| 608 |  | -	u16 data_len; | 
|---|
| 609 |  | -	u8 *data; | 
|---|
| 610 |  | -	int rc; | 
|---|
| 611 |  | - | 
|---|
| 612 |  | -	rc = tpm_buf_init(&buf, TPM2_ST_SESSIONS, TPM2_CC_UNSEAL); | 
|---|
| 613 |  | -	if (rc) | 
|---|
| 614 |  | -		return rc; | 
|---|
| 615 |  | - | 
|---|
| 616 |  | -	tpm_buf_append_u32(&buf, blob_handle); | 
|---|
| 617 |  | -	tpm2_buf_append_auth(&buf, | 
|---|
| 618 |  | -			     options->policyhandle ? | 
|---|
| 619 |  | -			     options->policyhandle : TPM2_RS_PW, | 
|---|
| 620 |  | -			     NULL /* nonce */, 0, | 
|---|
| 621 |  | -			     TPM2_SA_CONTINUE_SESSION, | 
|---|
| 622 |  | -			     options->blobauth /* hmac */, | 
|---|
| 623 |  | -			     TPM_DIGEST_SIZE); | 
|---|
| 624 |  | - | 
|---|
| 625 |  | -	rc = tpm_transmit_cmd(chip, NULL, buf.data, PAGE_SIZE, 6, flags, | 
|---|
| 626 |  | -			      "unsealing"); | 
|---|
| 627 |  | -	if (rc > 0) | 
|---|
| 628 |  | -		rc = -EPERM; | 
|---|
| 629 |  | - | 
|---|
| 630 |  | -	if (!rc) { | 
|---|
| 631 |  | -		data_len = be16_to_cpup( | 
|---|
| 632 |  | -			(__be16 *) &buf.data[TPM_HEADER_SIZE + 4]); | 
|---|
| 633 |  | -		if (data_len < MIN_KEY_SIZE ||  data_len > MAX_KEY_SIZE + 1) { | 
|---|
| 634 |  | -			rc = -EFAULT; | 
|---|
| 635 |  | -			goto out; | 
|---|
| 636 |  | -		} | 
|---|
| 637 |  | - | 
|---|
| 638 |  | -		if (tpm_buf_length(&buf) < TPM_HEADER_SIZE + 6 + data_len) { | 
|---|
| 639 |  | -			rc = -EFAULT; | 
|---|
| 640 |  | -			goto out; | 
|---|
| 641 |  | -		} | 
|---|
| 642 |  | -		data = &buf.data[TPM_HEADER_SIZE + 6]; | 
|---|
| 643 |  | - | 
|---|
| 644 |  | -		memcpy(payload->key, data, data_len - 1); | 
|---|
| 645 |  | -		payload->key_len = data_len - 1; | 
|---|
| 646 |  | -		payload->migratable = data[data_len - 1]; | 
|---|
| 647 |  | -	} | 
|---|
| 648 |  | - | 
|---|
| 649 |  | -out: | 
|---|
| 650 |  | -	tpm_buf_destroy(&buf); | 
|---|
| 651 |  | -	return rc; | 
|---|
| 652 |  | -} | 
|---|
| 653 |  | - | 
|---|
| 654 |  | -/** | 
|---|
| 655 |  | - * tpm2_unseal_trusted() - unseal the payload of a trusted key | 
|---|
| 656 |  | - * | 
|---|
| 657 |  | - * @chip: TPM chip to use | 
|---|
| 658 |  | - * @payload: the key data in clear and encrypted form | 
|---|
| 659 |  | - * @options: authentication values and other options | 
|---|
| 660 |  | - * | 
|---|
| 661 |  | - * Return: Same as with tpm_transmit_cmd. | 
|---|
| 662 |  | - */ | 
|---|
| 663 |  | -int tpm2_unseal_trusted(struct tpm_chip *chip, | 
|---|
| 664 |  | -			struct trusted_key_payload *payload, | 
|---|
| 665 |  | -			struct trusted_key_options *options) | 
|---|
| 666 |  | -{ | 
|---|
| 667 |  | -	u32 blob_handle; | 
|---|
| 668 |  | -	int rc; | 
|---|
| 669 |  | - | 
|---|
| 670 |  | -	mutex_lock(&chip->tpm_mutex); | 
|---|
| 671 |  | -	rc = tpm2_load_cmd(chip, payload, options, &blob_handle, | 
|---|
| 672 |  | -			   TPM_TRANSMIT_UNLOCKED); | 
|---|
| 673 |  | -	if (rc) | 
|---|
| 674 |  | -		goto out; | 
|---|
| 675 |  | - | 
|---|
| 676 |  | -	rc = tpm2_unseal_cmd(chip, payload, options, blob_handle, | 
|---|
| 677 |  | -			     TPM_TRANSMIT_UNLOCKED); | 
|---|
| 678 |  | -	tpm2_flush_context_cmd(chip, blob_handle, TPM_TRANSMIT_UNLOCKED); | 
|---|
| 679 |  | -out: | 
|---|
| 680 |  | -	mutex_unlock(&chip->tpm_mutex); | 
|---|
| 681 |  | -	return rc; | 
|---|
| 682 |  | -} | 
|---|
|  | 365 | +EXPORT_SYMBOL_GPL(tpm2_flush_context); | 
|---|
| 683 | 366 |  | 
|---|
| 684 | 367 | struct tpm2_get_cap_out { | 
|---|
| 685 | 368 | u8 more_data; | 
|---|
| .. | .. | 
|---|
| 713 | 396 | tpm_buf_append_u32(&buf, TPM2_CAP_TPM_PROPERTIES); | 
|---|
| 714 | 397 | tpm_buf_append_u32(&buf, property_id); | 
|---|
| 715 | 398 | tpm_buf_append_u32(&buf, 1); | 
|---|
| 716 |  | -	rc = tpm_transmit_cmd(chip, NULL, buf.data, PAGE_SIZE, 0, 0, NULL); | 
|---|
|  | 399 | +	rc = tpm_transmit_cmd(chip, &buf, 0, NULL); | 
|---|
| 717 | 400 | if (!rc) { | 
|---|
| 718 | 401 | out = (struct tpm2_get_cap_out *) | 
|---|
| 719 | 402 | &buf.data[TPM_HEADER_SIZE]; | 
|---|
| 720 |  | -		*value = be32_to_cpu(out->value); | 
|---|
|  | 403 | +		/* | 
|---|
|  | 404 | +		 * To prevent failing boot up of some systems, Infineon TPM2.0 | 
|---|
|  | 405 | +		 * returns SUCCESS on TPM2_Startup in field upgrade mode. Also | 
|---|
|  | 406 | +		 * the TPM2_Getcapability command returns a zero length list | 
|---|
|  | 407 | +		 * in field upgrade mode. | 
|---|
|  | 408 | +		 */ | 
|---|
|  | 409 | +		if (be32_to_cpu(out->property_cnt) > 0) | 
|---|
|  | 410 | +			*value = be32_to_cpu(out->value); | 
|---|
|  | 411 | +		else | 
|---|
|  | 412 | +			rc = -ENODATA; | 
|---|
| 721 | 413 | } | 
|---|
| 722 | 414 | tpm_buf_destroy(&buf); | 
|---|
| 723 | 415 | return rc; | 
|---|
| .. | .. | 
|---|
| 743 | 435 | if (rc) | 
|---|
| 744 | 436 | return; | 
|---|
| 745 | 437 | tpm_buf_append_u16(&buf, shutdown_type); | 
|---|
| 746 |  | -	tpm_transmit_cmd(chip, NULL, buf.data, PAGE_SIZE, 0, 0, | 
|---|
| 747 |  | -			 "stopping the TPM"); | 
|---|
|  | 438 | +	tpm_transmit_cmd(chip, &buf, 0, "stopping the TPM"); | 
|---|
| 748 | 439 | tpm_buf_destroy(&buf); | 
|---|
| 749 | 440 | } | 
|---|
| 750 |  | - | 
|---|
| 751 |  | -/* | 
|---|
| 752 |  | - * tpm2_calc_ordinal_duration() - maximum duration for a command | 
|---|
| 753 |  | - * | 
|---|
| 754 |  | - * @chip:	TPM chip to use. | 
|---|
| 755 |  | - * @ordinal:	command code number. | 
|---|
| 756 |  | - * | 
|---|
| 757 |  | - * Return: maximum duration for a command | 
|---|
| 758 |  | - */ | 
|---|
| 759 |  | -unsigned long tpm2_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal) | 
|---|
| 760 |  | -{ | 
|---|
| 761 |  | -	int index = TPM_UNDEFINED; | 
|---|
| 762 |  | -	int duration = 0; | 
|---|
| 763 |  | - | 
|---|
| 764 |  | -	if (ordinal >= TPM2_CC_FIRST && ordinal <= TPM2_CC_LAST) | 
|---|
| 765 |  | -		index = tpm2_ordinal_duration[ordinal - TPM2_CC_FIRST]; | 
|---|
| 766 |  | - | 
|---|
| 767 |  | -	if (index != TPM_UNDEFINED) | 
|---|
| 768 |  | -		duration = chip->duration[index]; | 
|---|
| 769 |  | - | 
|---|
| 770 |  | -	if (duration <= 0) | 
|---|
| 771 |  | -		duration = msecs_to_jiffies(TPM2_DURATION_DEFAULT); | 
|---|
| 772 |  | - | 
|---|
| 773 |  | -	return duration; | 
|---|
| 774 |  | -} | 
|---|
| 775 |  | -EXPORT_SYMBOL_GPL(tpm2_calc_ordinal_duration); | 
|---|
| 776 | 441 |  | 
|---|
| 777 | 442 | /** | 
|---|
| 778 | 443 | * tpm2_do_selftest() - ensure that all self tests have passed | 
|---|
| .. | .. | 
|---|
| 799 | 464 | return rc; | 
|---|
| 800 | 465 |  | 
|---|
| 801 | 466 | tpm_buf_append_u8(&buf, full); | 
|---|
| 802 |  | -		rc = tpm_transmit_cmd(chip, NULL, buf.data, PAGE_SIZE, 0, 0, | 
|---|
|  | 467 | +		rc = tpm_transmit_cmd(chip, &buf, 0, | 
|---|
| 803 | 468 | "attempting the self test"); | 
|---|
| 804 | 469 | tpm_buf_destroy(&buf); | 
|---|
| 805 | 470 |  | 
|---|
| .. | .. | 
|---|
| 826 | 491 | */ | 
|---|
| 827 | 492 | int tpm2_probe(struct tpm_chip *chip) | 
|---|
| 828 | 493 | { | 
|---|
| 829 |  | -	struct tpm_output_header *out; | 
|---|
|  | 494 | +	struct tpm_header *out; | 
|---|
| 830 | 495 | struct tpm_buf buf; | 
|---|
| 831 | 496 | int rc; | 
|---|
| 832 | 497 |  | 
|---|
| .. | .. | 
|---|
| 836 | 501 | tpm_buf_append_u32(&buf, TPM2_CAP_TPM_PROPERTIES); | 
|---|
| 837 | 502 | tpm_buf_append_u32(&buf, TPM_PT_TOTAL_COMMANDS); | 
|---|
| 838 | 503 | tpm_buf_append_u32(&buf, 1); | 
|---|
| 839 |  | -	rc = tpm_transmit_cmd(chip, NULL, buf.data, PAGE_SIZE, 0, 0, NULL); | 
|---|
|  | 504 | +	rc = tpm_transmit_cmd(chip, &buf, 0, NULL); | 
|---|
| 840 | 505 | /* We ignore TPM return codes on purpose. */ | 
|---|
| 841 | 506 | if (rc >=  0) { | 
|---|
| 842 |  | -		out = (struct tpm_output_header *)buf.data; | 
|---|
|  | 507 | +		out = (struct tpm_header *)buf.data; | 
|---|
| 843 | 508 | if (be16_to_cpu(out->tag) == TPM2_ST_NO_SESSIONS) | 
|---|
| 844 | 509 | chip->flags |= TPM_CHIP_FLAG_TPM2; | 
|---|
| 845 | 510 | } | 
|---|
| .. | .. | 
|---|
| 848 | 513 | } | 
|---|
| 849 | 514 | EXPORT_SYMBOL_GPL(tpm2_probe); | 
|---|
| 850 | 515 |  | 
|---|
|  | 516 | +static int tpm2_init_bank_info(struct tpm_chip *chip, u32 bank_index) | 
|---|
|  | 517 | +{ | 
|---|
|  | 518 | +	struct tpm_bank_info *bank = chip->allocated_banks + bank_index; | 
|---|
|  | 519 | +	struct tpm_digest digest = { .alg_id = bank->alg_id }; | 
|---|
|  | 520 | +	int i; | 
|---|
|  | 521 | + | 
|---|
|  | 522 | +	/* | 
|---|
|  | 523 | +	 * Avoid unnecessary PCR read operations to reduce overhead | 
|---|
|  | 524 | +	 * and obtain identifiers of the crypto subsystem. | 
|---|
|  | 525 | +	 */ | 
|---|
|  | 526 | +	for (i = 0; i < ARRAY_SIZE(tpm2_hash_map); i++) { | 
|---|
|  | 527 | +		enum hash_algo crypto_algo = tpm2_hash_map[i].crypto_id; | 
|---|
|  | 528 | + | 
|---|
|  | 529 | +		if (bank->alg_id != tpm2_hash_map[i].tpm_id) | 
|---|
|  | 530 | +			continue; | 
|---|
|  | 531 | + | 
|---|
|  | 532 | +		bank->digest_size = hash_digest_size[crypto_algo]; | 
|---|
|  | 533 | +		bank->crypto_id = crypto_algo; | 
|---|
|  | 534 | +		return 0; | 
|---|
|  | 535 | +	} | 
|---|
|  | 536 | + | 
|---|
|  | 537 | +	bank->crypto_id = HASH_ALGO__LAST; | 
|---|
|  | 538 | + | 
|---|
|  | 539 | +	return tpm2_pcr_read(chip, 0, &digest, &bank->digest_size); | 
|---|
|  | 540 | +} | 
|---|
|  | 541 | + | 
|---|
| 851 | 542 | struct tpm2_pcr_selection { | 
|---|
| 852 | 543 | __be16  hash_alg; | 
|---|
| 853 | 544 | u8  size_of_select; | 
|---|
| 854 | 545 | u8  pcr_select[3]; | 
|---|
| 855 | 546 | } __packed; | 
|---|
| 856 | 547 |  | 
|---|
| 857 |  | -static ssize_t tpm2_get_pcr_allocation(struct tpm_chip *chip) | 
|---|
|  | 548 | +ssize_t tpm2_get_pcr_allocation(struct tpm_chip *chip) | 
|---|
| 858 | 549 | { | 
|---|
| 859 | 550 | struct tpm2_pcr_selection pcr_selection; | 
|---|
| 860 | 551 | struct tpm_buf buf; | 
|---|
| 861 | 552 | void *marker; | 
|---|
| 862 | 553 | void *end; | 
|---|
| 863 | 554 | void *pcr_select_offset; | 
|---|
| 864 |  | -	unsigned int count; | 
|---|
| 865 | 555 | u32 sizeof_pcr_selection; | 
|---|
|  | 556 | +	u32 nr_possible_banks; | 
|---|
|  | 557 | +	u32 nr_alloc_banks = 0; | 
|---|
|  | 558 | +	u16 hash_alg; | 
|---|
| 866 | 559 | u32 rsp_len; | 
|---|
| 867 | 560 | int rc; | 
|---|
| 868 | 561 | int i = 0; | 
|---|
| .. | .. | 
|---|
| 875 | 568 | tpm_buf_append_u32(&buf, 0); | 
|---|
| 876 | 569 | tpm_buf_append_u32(&buf, 1); | 
|---|
| 877 | 570 |  | 
|---|
| 878 |  | -	rc = tpm_transmit_cmd(chip, NULL, buf.data, PAGE_SIZE, 9, 0, | 
|---|
| 879 |  | -			      "get tpm pcr allocation"); | 
|---|
|  | 571 | +	rc = tpm_transmit_cmd(chip, &buf, 9, "get tpm pcr allocation"); | 
|---|
| 880 | 572 | if (rc) | 
|---|
| 881 | 573 | goto out; | 
|---|
| 882 | 574 |  | 
|---|
| 883 |  | -	count = be32_to_cpup( | 
|---|
|  | 575 | +	nr_possible_banks = be32_to_cpup( | 
|---|
| 884 | 576 | (__be32 *)&buf.data[TPM_HEADER_SIZE + 5]); | 
|---|
| 885 | 577 |  | 
|---|
| 886 |  | -	if (count > ARRAY_SIZE(chip->active_banks)) { | 
|---|
| 887 |  | -		rc = -ENODEV; | 
|---|
|  | 578 | +	chip->allocated_banks = kcalloc(nr_possible_banks, | 
|---|
|  | 579 | +					sizeof(*chip->allocated_banks), | 
|---|
|  | 580 | +					GFP_KERNEL); | 
|---|
|  | 581 | +	if (!chip->allocated_banks) { | 
|---|
|  | 582 | +		rc = -ENOMEM; | 
|---|
| 888 | 583 | goto out; | 
|---|
| 889 | 584 | } | 
|---|
| 890 | 585 |  | 
|---|
| .. | .. | 
|---|
| 893 | 588 | rsp_len = be32_to_cpup((__be32 *)&buf.data[2]); | 
|---|
| 894 | 589 | end = &buf.data[rsp_len]; | 
|---|
| 895 | 590 |  | 
|---|
| 896 |  | -	for (i = 0; i < count; i++) { | 
|---|
|  | 591 | +	for (i = 0; i < nr_possible_banks; i++) { | 
|---|
| 897 | 592 | pcr_select_offset = marker + | 
|---|
| 898 | 593 | offsetof(struct tpm2_pcr_selection, size_of_select); | 
|---|
| 899 | 594 | if (pcr_select_offset >= end) { | 
|---|
| .. | .. | 
|---|
| 902 | 597 | } | 
|---|
| 903 | 598 |  | 
|---|
| 904 | 599 | memcpy(&pcr_selection, marker, sizeof(pcr_selection)); | 
|---|
| 905 |  | -		chip->active_banks[i] = be16_to_cpu(pcr_selection.hash_alg); | 
|---|
|  | 600 | +		hash_alg = be16_to_cpu(pcr_selection.hash_alg); | 
|---|
|  | 601 | + | 
|---|
|  | 602 | +		pcr_select_offset = memchr_inv(pcr_selection.pcr_select, 0, | 
|---|
|  | 603 | +					       pcr_selection.size_of_select); | 
|---|
|  | 604 | +		if (pcr_select_offset) { | 
|---|
|  | 605 | +			chip->allocated_banks[nr_alloc_banks].alg_id = hash_alg; | 
|---|
|  | 606 | + | 
|---|
|  | 607 | +			rc = tpm2_init_bank_info(chip, nr_alloc_banks); | 
|---|
|  | 608 | +			if (rc < 0) | 
|---|
|  | 609 | +				break; | 
|---|
|  | 610 | + | 
|---|
|  | 611 | +			nr_alloc_banks++; | 
|---|
|  | 612 | +		} | 
|---|
|  | 613 | + | 
|---|
| 906 | 614 | sizeof_pcr_selection = sizeof(pcr_selection.hash_alg) + | 
|---|
| 907 | 615 | sizeof(pcr_selection.size_of_select) + | 
|---|
| 908 | 616 | pcr_selection.size_of_select; | 
|---|
| 909 | 617 | marker = marker + sizeof_pcr_selection; | 
|---|
| 910 | 618 | } | 
|---|
| 911 | 619 |  | 
|---|
|  | 620 | +	chip->nr_allocated_banks = nr_alloc_banks; | 
|---|
| 912 | 621 | out: | 
|---|
| 913 |  | -	if (i < ARRAY_SIZE(chip->active_banks)) | 
|---|
| 914 |  | -		chip->active_banks[i] = TPM2_ALG_ERROR; | 
|---|
| 915 |  | - | 
|---|
| 916 | 622 | tpm_buf_destroy(&buf); | 
|---|
| 917 | 623 |  | 
|---|
| 918 | 624 | return rc; | 
|---|
| 919 | 625 | } | 
|---|
| 920 | 626 |  | 
|---|
| 921 |  | -static int tpm2_get_cc_attrs_tbl(struct tpm_chip *chip) | 
|---|
|  | 627 | +int tpm2_get_cc_attrs_tbl(struct tpm_chip *chip) | 
|---|
| 922 | 628 | { | 
|---|
| 923 | 629 | struct tpm_buf buf; | 
|---|
| 924 | 630 | u32 nr_commands; | 
|---|
| .. | .. | 
|---|
| 951 | 657 | tpm_buf_append_u32(&buf, TPM2_CC_FIRST); | 
|---|
| 952 | 658 | tpm_buf_append_u32(&buf, nr_commands); | 
|---|
| 953 | 659 |  | 
|---|
| 954 |  | -	rc = tpm_transmit_cmd(chip, NULL, buf.data, PAGE_SIZE, | 
|---|
| 955 |  | -			      9 + 4 * nr_commands, 0, NULL); | 
|---|
|  | 660 | +	rc = tpm_transmit_cmd(chip, &buf, 9 + 4 * nr_commands, NULL); | 
|---|
| 956 | 661 | if (rc) { | 
|---|
| 957 | 662 | tpm_buf_destroy(&buf); | 
|---|
| 958 | 663 | goto out; | 
|---|
| .. | .. | 
|---|
| 986 | 691 | rc = -ENODEV; | 
|---|
| 987 | 692 | return rc; | 
|---|
| 988 | 693 | } | 
|---|
|  | 694 | +EXPORT_SYMBOL_GPL(tpm2_get_cc_attrs_tbl); | 
|---|
|  | 695 | + | 
|---|
|  | 696 | +/** | 
|---|
|  | 697 | + * tpm2_startup - turn on the TPM | 
|---|
|  | 698 | + * @chip: TPM chip to use | 
|---|
|  | 699 | + * | 
|---|
|  | 700 | + * Normally the firmware should start the TPM. This function is provided as a | 
|---|
|  | 701 | + * workaround if this does not happen. A legal case for this could be for | 
|---|
|  | 702 | + * example when a TPM emulator is used. | 
|---|
|  | 703 | + * | 
|---|
|  | 704 | + * Return: same as tpm_transmit_cmd() | 
|---|
|  | 705 | + */ | 
|---|
|  | 706 | + | 
|---|
|  | 707 | +static int tpm2_startup(struct tpm_chip *chip) | 
|---|
|  | 708 | +{ | 
|---|
|  | 709 | +	struct tpm_buf buf; | 
|---|
|  | 710 | +	int rc; | 
|---|
|  | 711 | + | 
|---|
|  | 712 | +	dev_info(&chip->dev, "starting up the TPM manually\n"); | 
|---|
|  | 713 | + | 
|---|
|  | 714 | +	rc = tpm_buf_init(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_STARTUP); | 
|---|
|  | 715 | +	if (rc < 0) | 
|---|
|  | 716 | +		return rc; | 
|---|
|  | 717 | + | 
|---|
|  | 718 | +	tpm_buf_append_u16(&buf, TPM2_SU_CLEAR); | 
|---|
|  | 719 | +	rc = tpm_transmit_cmd(chip, &buf, 0, "attempting to start the TPM"); | 
|---|
|  | 720 | +	tpm_buf_destroy(&buf); | 
|---|
|  | 721 | + | 
|---|
|  | 722 | +	return rc; | 
|---|
|  | 723 | +} | 
|---|
| 989 | 724 |  | 
|---|
| 990 | 725 | /** | 
|---|
| 991 | 726 | * tpm2_auto_startup - Perform the standard automatic TPM initialization | 
|---|
| .. | .. | 
|---|
| 998 | 733 | { | 
|---|
| 999 | 734 | int rc; | 
|---|
| 1000 | 735 |  | 
|---|
| 1001 |  | -	rc = tpm_get_timeouts(chip); | 
|---|
|  | 736 | +	rc = tpm2_get_timeouts(chip); | 
|---|
| 1002 | 737 | if (rc) | 
|---|
| 1003 | 738 | goto out; | 
|---|
| 1004 | 739 |  | 
|---|
| .. | .. | 
|---|
| 1007 | 742 | goto out; | 
|---|
| 1008 | 743 |  | 
|---|
| 1009 | 744 | if (rc == TPM2_RC_INITIALIZE) { | 
|---|
| 1010 |  | -		rc = tpm_startup(chip); | 
|---|
|  | 745 | +		rc = tpm2_startup(chip); | 
|---|
| 1011 | 746 | if (rc) | 
|---|
| 1012 | 747 | goto out; | 
|---|
| 1013 | 748 |  | 
|---|
| .. | .. | 
|---|
| 1015 | 750 | if (rc) | 
|---|
| 1016 | 751 | goto out; | 
|---|
| 1017 | 752 | } | 
|---|
| 1018 |  | - | 
|---|
| 1019 |  | -	rc = tpm2_get_pcr_allocation(chip); | 
|---|
| 1020 |  | -	if (rc) | 
|---|
| 1021 |  | -		goto out; | 
|---|
| 1022 | 753 |  | 
|---|
| 1023 | 754 | rc = tpm2_get_cc_attrs_tbl(chip); | 
|---|
| 1024 | 755 |  | 
|---|