Commit dabd40ec authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'tpmdd-next-v5.17-fixed' of...

Merge tag 'tpmdd-next-v5.17-fixed' of git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd

Pull TPM updates from Jarkko Sakkinen:
 "Other than bug fixes for TPM, this includes a patch for asymmetric
  keys to allow to look up and verify with self-signed certificates
  (keys without so called AKID - Authority Key Identifier) using a new
  "dn:" prefix in the query"

* tag 'tpmdd-next-v5.17-fixed' of git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd:
  lib: remove redundant assignment to variable ret
  tpm: fix NPE on probe for missing device
  tpm: fix potential NULL pointer access in tpm_del_char_device
  tpm: Add Upgrade/Reduced mode support for TPM2 modules
  char: tpm: cr50: Set TPM_FIRMWARE_POWER_MANAGED based on device property
  keys: X.509 public key issuer lookup without AKID
  tpm_tis: Fix an error handling path in 'tpm_tis_core_init()'
  tpm: tpm_tis_spi_cr50: Add default RNG quality
  tpm/st33zp24: drop unneeded over-commenting
  tpm: add request_locality before write TPM_INT_ENABLE
parents 4aa1b825 d99a8af4
...@@ -36,16 +36,23 @@ static DECLARE_RWSEM(asymmetric_key_parsers_sem); ...@@ -36,16 +36,23 @@ static DECLARE_RWSEM(asymmetric_key_parsers_sem);
* find_asymmetric_key - Find a key by ID. * find_asymmetric_key - Find a key by ID.
* @keyring: The keys to search. * @keyring: The keys to search.
* @id_0: The first ID to look for or NULL. * @id_0: The first ID to look for or NULL.
* @id_1: The second ID to look for or NULL. * @id_1: The second ID to look for or NULL, matched together with @id_0
* @partial: Use partial match if true, exact if false. * against @keyring keys' id[0] and id[1].
* @id_2: The fallback ID to match against @keyring keys' id[2] if both of the
* other IDs are NULL.
* @partial: Use partial match for @id_0 and @id_1 if true, exact if false.
* *
* Find a key in the given keyring by identifier. The preferred identifier is * Find a key in the given keyring by identifier. The preferred identifier is
* the id_0 and the fallback identifier is the id_1. If both are given, the * the id_0 and the fallback identifier is the id_1. If both are given, the
* lookup is by the former, but the latter must also match. * former is matched (exactly or partially) against either of the sought key's
* identifiers and the latter must match the found key's second identifier
* exactly. If both are missing, id_2 must match the sought key's third
* identifier exactly.
*/ */
struct key *find_asymmetric_key(struct key *keyring, struct key *find_asymmetric_key(struct key *keyring,
const struct asymmetric_key_id *id_0, const struct asymmetric_key_id *id_0,
const struct asymmetric_key_id *id_1, const struct asymmetric_key_id *id_1,
const struct asymmetric_key_id *id_2,
bool partial) bool partial)
{ {
struct key *key; struct key *key;
...@@ -54,14 +61,17 @@ struct key *find_asymmetric_key(struct key *keyring, ...@@ -54,14 +61,17 @@ struct key *find_asymmetric_key(struct key *keyring,
char *req, *p; char *req, *p;
int len; int len;
BUG_ON(!id_0 && !id_1); WARN_ON(!id_0 && !id_1 && !id_2);
if (id_0) { if (id_0) {
lookup = id_0->data; lookup = id_0->data;
len = id_0->len; len = id_0->len;
} else { } else if (id_1) {
lookup = id_1->data; lookup = id_1->data;
len = id_1->len; len = id_1->len;
} else {
lookup = id_2->data;
len = id_2->len;
} }
/* Construct an identifier "id:<keyid>". */ /* Construct an identifier "id:<keyid>". */
...@@ -69,7 +79,10 @@ struct key *find_asymmetric_key(struct key *keyring, ...@@ -69,7 +79,10 @@ struct key *find_asymmetric_key(struct key *keyring,
if (!req) if (!req)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
if (partial) { if (!id_0 && !id_1) {
*p++ = 'd';
*p++ = 'n';
} else if (partial) {
*p++ = 'i'; *p++ = 'i';
*p++ = 'd'; *p++ = 'd';
} else { } else {
...@@ -185,8 +198,8 @@ bool asymmetric_key_id_partial(const struct asymmetric_key_id *kid1, ...@@ -185,8 +198,8 @@ bool asymmetric_key_id_partial(const struct asymmetric_key_id *kid1,
EXPORT_SYMBOL_GPL(asymmetric_key_id_partial); EXPORT_SYMBOL_GPL(asymmetric_key_id_partial);
/** /**
* asymmetric_match_key_ids - Search asymmetric key IDs * asymmetric_match_key_ids - Search asymmetric key IDs 1 & 2
* @kids: The list of key IDs to check * @kids: The pair of key IDs to check
* @match_id: The key ID we're looking for * @match_id: The key ID we're looking for
* @match: The match function to use * @match: The match function to use
*/ */
...@@ -200,7 +213,7 @@ static bool asymmetric_match_key_ids( ...@@ -200,7 +213,7 @@ static bool asymmetric_match_key_ids(
if (!kids || !match_id) if (!kids || !match_id)
return false; return false;
for (i = 0; i < ARRAY_SIZE(kids->id); i++) for (i = 0; i < 2; i++)
if (match(kids->id[i], match_id)) if (match(kids->id[i], match_id))
return true; return true;
return false; return false;
...@@ -244,7 +257,7 @@ struct asymmetric_key_id *asymmetric_key_hex_to_key_id(const char *id) ...@@ -244,7 +257,7 @@ struct asymmetric_key_id *asymmetric_key_hex_to_key_id(const char *id)
} }
/* /*
* Match asymmetric keys by an exact match on an ID. * Match asymmetric keys by an exact match on one of the first two IDs.
*/ */
static bool asymmetric_key_cmp(const struct key *key, static bool asymmetric_key_cmp(const struct key *key,
const struct key_match_data *match_data) const struct key_match_data *match_data)
...@@ -257,7 +270,7 @@ static bool asymmetric_key_cmp(const struct key *key, ...@@ -257,7 +270,7 @@ static bool asymmetric_key_cmp(const struct key *key,
} }
/* /*
* Match asymmetric keys by a partial match on an IDs. * Match asymmetric keys by a partial match on one of the first two IDs.
*/ */
static bool asymmetric_key_cmp_partial(const struct key *key, static bool asymmetric_key_cmp_partial(const struct key *key,
const struct key_match_data *match_data) const struct key_match_data *match_data)
...@@ -269,6 +282,18 @@ static bool asymmetric_key_cmp_partial(const struct key *key, ...@@ -269,6 +282,18 @@ static bool asymmetric_key_cmp_partial(const struct key *key,
asymmetric_key_id_partial); asymmetric_key_id_partial);
} }
/*
* Match asymmetric keys by an exact match on the third IDs.
*/
static bool asymmetric_key_cmp_name(const struct key *key,
const struct key_match_data *match_data)
{
const struct asymmetric_key_ids *kids = asymmetric_key_ids(key);
const struct asymmetric_key_id *match_id = match_data->preparsed;
return kids && asymmetric_key_id_same(kids->id[2], match_id);
}
/* /*
* Preparse the match criterion. If we don't set lookup_type and cmp, * Preparse the match criterion. If we don't set lookup_type and cmp,
* the default will be an exact match on the key description. * the default will be an exact match on the key description.
...@@ -276,8 +301,9 @@ static bool asymmetric_key_cmp_partial(const struct key *key, ...@@ -276,8 +301,9 @@ static bool asymmetric_key_cmp_partial(const struct key *key,
* There are some specifiers for matching key IDs rather than by the key * There are some specifiers for matching key IDs rather than by the key
* description: * description:
* *
* "id:<id>" - find a key by partial match on any available ID * "id:<id>" - find a key by partial match on one of the first two IDs
* "ex:<id>" - find a key by exact match on any available ID * "ex:<id>" - find a key by exact match on one of the first two IDs
* "dn:<id>" - find a key by exact match on the third ID
* *
* These have to be searched by iteration rather than by direct lookup because * These have to be searched by iteration rather than by direct lookup because
* the key is hashed according to its description. * the key is hashed according to its description.
...@@ -301,6 +327,11 @@ static int asymmetric_key_match_preparse(struct key_match_data *match_data) ...@@ -301,6 +327,11 @@ static int asymmetric_key_match_preparse(struct key_match_data *match_data)
spec[1] == 'x' && spec[1] == 'x' &&
spec[2] == ':') { spec[2] == ':') {
id = spec + 3; id = spec + 3;
} else if (spec[0] == 'd' &&
spec[1] == 'n' &&
spec[2] == ':') {
id = spec + 3;
cmp = asymmetric_key_cmp_name;
} else { } else {
goto default_match; goto default_match;
} }
......
...@@ -48,7 +48,7 @@ static int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7, ...@@ -48,7 +48,7 @@ static int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7,
* keys. * keys.
*/ */
key = find_asymmetric_key(trust_keyring, key = find_asymmetric_key(trust_keyring,
x509->id, x509->skid, false); x509->id, x509->skid, NULL, false);
if (!IS_ERR(key)) { if (!IS_ERR(key)) {
/* One of the X.509 certificates in the PKCS#7 message /* One of the X.509 certificates in the PKCS#7 message
* is apparently the same as one we already trust. * is apparently the same as one we already trust.
...@@ -82,7 +82,7 @@ static int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7, ...@@ -82,7 +82,7 @@ static int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7,
key = find_asymmetric_key(trust_keyring, key = find_asymmetric_key(trust_keyring,
last->sig->auth_ids[0], last->sig->auth_ids[0],
last->sig->auth_ids[1], last->sig->auth_ids[1],
false); NULL, false);
if (!IS_ERR(key)) { if (!IS_ERR(key)) {
x509 = last; x509 = last;
pr_devel("sinfo %u: Root cert %u signer is key %x\n", pr_devel("sinfo %u: Root cert %u signer is key %x\n",
...@@ -97,7 +97,7 @@ static int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7, ...@@ -97,7 +97,7 @@ static int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7,
* the signed info directly. * the signed info directly.
*/ */
key = find_asymmetric_key(trust_keyring, key = find_asymmetric_key(trust_keyring,
sinfo->sig->auth_ids[0], NULL, false); sinfo->sig->auth_ids[0], NULL, NULL, false);
if (!IS_ERR(key)) { if (!IS_ERR(key)) {
pr_devel("sinfo %u: Direct signer is key %x\n", pr_devel("sinfo %u: Direct signer is key %x\n",
sinfo->index, key_serial(key)); sinfo->index, key_serial(key));
......
...@@ -87,7 +87,7 @@ int restrict_link_by_signature(struct key *dest_keyring, ...@@ -87,7 +87,7 @@ int restrict_link_by_signature(struct key *dest_keyring,
sig = payload->data[asym_auth]; sig = payload->data[asym_auth];
if (!sig) if (!sig)
return -ENOPKG; return -ENOPKG;
if (!sig->auth_ids[0] && !sig->auth_ids[1]) if (!sig->auth_ids[0] && !sig->auth_ids[1] && !sig->auth_ids[2])
return -ENOKEY; return -ENOKEY;
if (ca_keyid && !asymmetric_key_id_partial(sig->auth_ids[1], ca_keyid)) if (ca_keyid && !asymmetric_key_id_partial(sig->auth_ids[1], ca_keyid))
...@@ -96,7 +96,7 @@ int restrict_link_by_signature(struct key *dest_keyring, ...@@ -96,7 +96,7 @@ int restrict_link_by_signature(struct key *dest_keyring,
/* See if we have a key that signed this one. */ /* See if we have a key that signed this one. */
key = find_asymmetric_key(trust_keyring, key = find_asymmetric_key(trust_keyring,
sig->auth_ids[0], sig->auth_ids[1], sig->auth_ids[0], sig->auth_ids[1],
false); sig->auth_ids[2], false);
if (IS_ERR(key)) if (IS_ERR(key))
return -ENOKEY; return -ENOKEY;
...@@ -108,11 +108,11 @@ int restrict_link_by_signature(struct key *dest_keyring, ...@@ -108,11 +108,11 @@ int restrict_link_by_signature(struct key *dest_keyring,
return ret; return ret;
} }
static bool match_either_id(const struct asymmetric_key_ids *pair, static bool match_either_id(const struct asymmetric_key_id **pair,
const struct asymmetric_key_id *single) const struct asymmetric_key_id *single)
{ {
return (asymmetric_key_id_same(pair->id[0], single) || return (asymmetric_key_id_same(pair[0], single) ||
asymmetric_key_id_same(pair->id[1], single)); asymmetric_key_id_same(pair[1], single));
} }
static int key_or_keyring_common(struct key *dest_keyring, static int key_or_keyring_common(struct key *dest_keyring,
...@@ -140,20 +140,22 @@ static int key_or_keyring_common(struct key *dest_keyring, ...@@ -140,20 +140,22 @@ static int key_or_keyring_common(struct key *dest_keyring,
sig = payload->data[asym_auth]; sig = payload->data[asym_auth];
if (!sig) if (!sig)
return -ENOPKG; return -ENOPKG;
if (!sig->auth_ids[0] && !sig->auth_ids[1]) if (!sig->auth_ids[0] && !sig->auth_ids[1] && !sig->auth_ids[2])
return -ENOKEY; return -ENOKEY;
if (trusted) { if (trusted) {
if (trusted->type == &key_type_keyring) { if (trusted->type == &key_type_keyring) {
/* See if we have a key that signed this one. */ /* See if we have a key that signed this one. */
key = find_asymmetric_key(trusted, sig->auth_ids[0], key = find_asymmetric_key(trusted, sig->auth_ids[0],
sig->auth_ids[1], false); sig->auth_ids[1],
sig->auth_ids[2], false);
if (IS_ERR(key)) if (IS_ERR(key))
key = NULL; key = NULL;
} else if (trusted->type == &key_type_asymmetric) { } else if (trusted->type == &key_type_asymmetric) {
const struct asymmetric_key_ids *signer_ids; const struct asymmetric_key_id **signer_ids;
signer_ids = asymmetric_key_ids(trusted); signer_ids = (const struct asymmetric_key_id **)
asymmetric_key_ids(trusted)->id;
/* /*
* The auth_ids come from the candidate key (the * The auth_ids come from the candidate key (the
...@@ -164,22 +166,29 @@ static int key_or_keyring_common(struct key *dest_keyring, ...@@ -164,22 +166,29 @@ static int key_or_keyring_common(struct key *dest_keyring,
* The signer_ids are identifiers for the * The signer_ids are identifiers for the
* signing key specified for dest_keyring. * signing key specified for dest_keyring.
* *
* The first auth_id is the preferred id, and * The first auth_id is the preferred id, 2nd and
* the second is the fallback. If only one * 3rd are the fallbacks. If exactly one of
* auth_id is present, it may match against * auth_ids[0] and auth_ids[1] is present, it may
* either signer_id. If two auth_ids are * match either signer_ids[0] or signed_ids[1].
* present, the first auth_id must match one * If both are present the first one may match
* signer_id and the second auth_id must match * either signed_id but the second one must match
* the second signer_id. * the second signer_id. If neither of them is
* available, auth_ids[2] is matched against
* signer_ids[2] as a fallback.
*/ */
if (!sig->auth_ids[0] || !sig->auth_ids[1]) { if (!sig->auth_ids[0] && !sig->auth_ids[1]) {
if (asymmetric_key_id_same(signer_ids[2],
sig->auth_ids[2]))
key = __key_get(trusted);
} else if (!sig->auth_ids[0] || !sig->auth_ids[1]) {
const struct asymmetric_key_id *auth_id; const struct asymmetric_key_id *auth_id;
auth_id = sig->auth_ids[0] ?: sig->auth_ids[1]; auth_id = sig->auth_ids[0] ?: sig->auth_ids[1];
if (match_either_id(signer_ids, auth_id)) if (match_either_id(signer_ids, auth_id))
key = __key_get(trusted); key = __key_get(trusted);
} else if (asymmetric_key_id_same(signer_ids->id[1], } else if (asymmetric_key_id_same(signer_ids[1],
sig->auth_ids[1]) && sig->auth_ids[1]) &&
match_either_id(signer_ids, match_either_id(signer_ids,
sig->auth_ids[0])) { sig->auth_ids[0])) {
...@@ -193,7 +202,8 @@ static int key_or_keyring_common(struct key *dest_keyring, ...@@ -193,7 +202,8 @@ static int key_or_keyring_common(struct key *dest_keyring,
if (check_dest && !key) { if (check_dest && !key) {
/* See if the destination has a key that signed this one. */ /* See if the destination has a key that signed this one. */
key = find_asymmetric_key(dest_keyring, sig->auth_ids[0], key = find_asymmetric_key(dest_keyring, sig->auth_ids[0],
sig->auth_ids[1], false); sig->auth_ids[1], sig->auth_ids[2],
false);
if (IS_ERR(key)) if (IS_ERR(key))
key = NULL; key = NULL;
} }
......
...@@ -441,8 +441,18 @@ int x509_note_issuer(void *context, size_t hdrlen, ...@@ -441,8 +441,18 @@ int x509_note_issuer(void *context, size_t hdrlen,
const void *value, size_t vlen) const void *value, size_t vlen)
{ {
struct x509_parse_context *ctx = context; struct x509_parse_context *ctx = context;
struct asymmetric_key_id *kid;
ctx->cert->raw_issuer = value; ctx->cert->raw_issuer = value;
ctx->cert->raw_issuer_size = vlen; ctx->cert->raw_issuer_size = vlen;
if (!ctx->cert->sig->auth_ids[2]) {
kid = asymmetric_key_generate_id(value, vlen, "", 0);
if (IS_ERR(kid))
return PTR_ERR(kid);
ctx->cert->sig->auth_ids[2] = kid;
}
return x509_fabricate_name(ctx, hdrlen, tag, &ctx->cert->issuer, vlen); return x509_fabricate_name(ctx, hdrlen, tag, &ctx->cert->issuer, vlen);
} }
......
...@@ -223,6 +223,13 @@ static int x509_key_preparse(struct key_preparsed_payload *prep) ...@@ -223,6 +223,13 @@ static int x509_key_preparse(struct key_preparsed_payload *prep)
goto error_free_desc; goto error_free_desc;
kids->id[0] = cert->id; kids->id[0] = cert->id;
kids->id[1] = cert->skid; kids->id[1] = cert->skid;
kids->id[2] = asymmetric_key_generate_id(cert->raw_subject,
cert->raw_subject_size,
"", 0);
if (IS_ERR(kids->id[2])) {
ret = PTR_ERR(kids->id[2]);
goto error_free_kids;
}
/* We're pinning the module by being linked against it */ /* We're pinning the module by being linked against it */
__module_get(public_key_subtype.owner); __module_get(public_key_subtype.owner);
...@@ -239,8 +246,11 @@ static int x509_key_preparse(struct key_preparsed_payload *prep) ...@@ -239,8 +246,11 @@ static int x509_key_preparse(struct key_preparsed_payload *prep)
cert->skid = NULL; cert->skid = NULL;
cert->sig = NULL; cert->sig = NULL;
desc = NULL; desc = NULL;
kids = NULL;
ret = 0; ret = 0;
error_free_kids:
kfree(kids);
error_free_desc: error_free_desc:
kfree(desc); kfree(desc);
error_free_cert: error_free_cert:
......
...@@ -61,9 +61,7 @@ enum tis_defaults { ...@@ -61,9 +61,7 @@ enum tis_defaults {
}; };
/* /*
* clear_interruption clear the pending interrupt. * clear the pending interrupt.
* @param: tpm_dev, the tpm device device.
* @return: the interrupt status value.
*/ */
static u8 clear_interruption(struct st33zp24_dev *tpm_dev) static u8 clear_interruption(struct st33zp24_dev *tpm_dev)
{ {
...@@ -72,12 +70,10 @@ static u8 clear_interruption(struct st33zp24_dev *tpm_dev) ...@@ -72,12 +70,10 @@ static u8 clear_interruption(struct st33zp24_dev *tpm_dev)
tpm_dev->ops->recv(tpm_dev->phy_id, TPM_INT_STATUS, &interrupt, 1); tpm_dev->ops->recv(tpm_dev->phy_id, TPM_INT_STATUS, &interrupt, 1);
tpm_dev->ops->send(tpm_dev->phy_id, TPM_INT_STATUS, &interrupt, 1); tpm_dev->ops->send(tpm_dev->phy_id, TPM_INT_STATUS, &interrupt, 1);
return interrupt; return interrupt;
} /* clear_interruption() */ }
/* /*
* st33zp24_cancel, cancel the current command execution or * cancel the current command execution or set STS to COMMAND READY.
* set STS to COMMAND READY.
* @param: chip, the tpm_chip description as specified in driver/char/tpm/tpm.h
*/ */
static void st33zp24_cancel(struct tpm_chip *chip) static void st33zp24_cancel(struct tpm_chip *chip)
{ {
...@@ -86,12 +82,10 @@ static void st33zp24_cancel(struct tpm_chip *chip) ...@@ -86,12 +82,10 @@ static void st33zp24_cancel(struct tpm_chip *chip)
data = TPM_STS_COMMAND_READY; data = TPM_STS_COMMAND_READY;
tpm_dev->ops->send(tpm_dev->phy_id, TPM_STS, &data, 1); tpm_dev->ops->send(tpm_dev->phy_id, TPM_STS, &data, 1);
} /* st33zp24_cancel() */ }
/* /*
* st33zp24_status return the TPM_STS register * return the TPM_STS register
* @param: chip, the tpm chip description
* @return: the TPM_STS register value.
*/ */
static u8 st33zp24_status(struct tpm_chip *chip) static u8 st33zp24_status(struct tpm_chip *chip)
{ {
...@@ -100,12 +94,10 @@ static u8 st33zp24_status(struct tpm_chip *chip) ...@@ -100,12 +94,10 @@ static u8 st33zp24_status(struct tpm_chip *chip)
tpm_dev->ops->recv(tpm_dev->phy_id, TPM_STS, &data, 1); tpm_dev->ops->recv(tpm_dev->phy_id, TPM_STS, &data, 1);
return data; return data;
} /* st33zp24_status() */ }
/* /*
* check_locality if the locality is active * if the locality is active
* @param: chip, the tpm chip description
* @return: true if LOCALITY0 is active, otherwise false
*/ */
static bool check_locality(struct tpm_chip *chip) static bool check_locality(struct tpm_chip *chip)
{ {
...@@ -120,13 +112,8 @@ static bool check_locality(struct tpm_chip *chip) ...@@ -120,13 +112,8 @@ static bool check_locality(struct tpm_chip *chip)
return true; return true;
return false; return false;
} /* check_locality() */ }
/*
* request_locality request the TPM locality
* @param: chip, the chip description
* @return: the active locality or negative value.
*/
static int request_locality(struct tpm_chip *chip) static int request_locality(struct tpm_chip *chip)
{ {
struct st33zp24_dev *tpm_dev = dev_get_drvdata(&chip->dev); struct st33zp24_dev *tpm_dev = dev_get_drvdata(&chip->dev);
...@@ -153,12 +140,8 @@ static int request_locality(struct tpm_chip *chip) ...@@ -153,12 +140,8 @@ static int request_locality(struct tpm_chip *chip)
/* could not get locality */ /* could not get locality */
return -EACCES; return -EACCES;
} /* request_locality() */ }
/*
* release_locality release the active locality
* @param: chip, the tpm chip description.
*/
static void release_locality(struct tpm_chip *chip) static void release_locality(struct tpm_chip *chip)
{ {
struct st33zp24_dev *tpm_dev = dev_get_drvdata(&chip->dev); struct st33zp24_dev *tpm_dev = dev_get_drvdata(&chip->dev);
...@@ -171,8 +154,6 @@ static void release_locality(struct tpm_chip *chip) ...@@ -171,8 +154,6 @@ static void release_locality(struct tpm_chip *chip)
/* /*
* get_burstcount return the burstcount value * get_burstcount return the burstcount value
* @param: chip, the chip description
* return: the burstcount or negative value.
*/ */
static int get_burstcount(struct tpm_chip *chip) static int get_burstcount(struct tpm_chip *chip)
{ {
...@@ -200,18 +181,8 @@ static int get_burstcount(struct tpm_chip *chip) ...@@ -200,18 +181,8 @@ static int get_burstcount(struct tpm_chip *chip)
msleep(TPM_TIMEOUT); msleep(TPM_TIMEOUT);
} while (time_before(jiffies, stop)); } while (time_before(jiffies, stop));
return -EBUSY; return -EBUSY;
} /* get_burstcount() */ }
/*
* wait_for_tpm_stat_cond
* @param: chip, chip description
* @param: mask, expected mask value
* @param: check_cancel, does the command expected to be canceled ?
* @param: canceled, did we received a cancel request ?
* @return: true if status == mask or if the command is canceled.
* false in other cases.
*/
static bool wait_for_tpm_stat_cond(struct tpm_chip *chip, u8 mask, static bool wait_for_tpm_stat_cond(struct tpm_chip *chip, u8 mask,
bool check_cancel, bool *canceled) bool check_cancel, bool *canceled)
{ {
...@@ -228,13 +199,7 @@ static bool wait_for_tpm_stat_cond(struct tpm_chip *chip, u8 mask, ...@@ -228,13 +199,7 @@ static bool wait_for_tpm_stat_cond(struct tpm_chip *chip, u8 mask,
} }
/* /*
* wait_for_stat wait for a TPM_STS value * wait for a TPM_STS value
* @param: chip, the tpm chip description
* @param: mask, the value mask to wait
* @param: timeout, the timeout
* @param: queue, the wait queue.
* @param: check_cancel, does the command can be cancelled ?
* @return: the tpm status, 0 if success, -ETIME if timeout is reached.
*/ */
static int wait_for_stat(struct tpm_chip *chip, u8 mask, unsigned long timeout, static int wait_for_stat(struct tpm_chip *chip, u8 mask, unsigned long timeout,
wait_queue_head_t *queue, bool check_cancel) wait_queue_head_t *queue, bool check_cancel)
...@@ -292,15 +257,8 @@ static int wait_for_stat(struct tpm_chip *chip, u8 mask, unsigned long timeout, ...@@ -292,15 +257,8 @@ static int wait_for_stat(struct tpm_chip *chip, u8 mask, unsigned long timeout,
} }
return -ETIME; return -ETIME;
} /* wait_for_stat() */ }
/*
* recv_data receive data
* @param: chip, the tpm chip description
* @param: buf, the buffer where the data are received
* @param: count, the number of data to receive
* @return: the number of bytes read from TPM FIFO.
*/
static int recv_data(struct tpm_chip *chip, u8 *buf, size_t count) static int recv_data(struct tpm_chip *chip, u8 *buf, size_t count)
{ {
struct st33zp24_dev *tpm_dev = dev_get_drvdata(&chip->dev); struct st33zp24_dev *tpm_dev = dev_get_drvdata(&chip->dev);
...@@ -325,12 +283,6 @@ static int recv_data(struct tpm_chip *chip, u8 *buf, size_t count) ...@@ -325,12 +283,6 @@ static int recv_data(struct tpm_chip *chip, u8 *buf, size_t count)
return size; return size;
} }
/*
* tpm_ioserirq_handler the serirq irq handler
* @param: irq, the tpm chip description
* @param: dev_id, the description of the chip
* @return: the status of the handler.
*/
static irqreturn_t tpm_ioserirq_handler(int irq, void *dev_id) static irqreturn_t tpm_ioserirq_handler(int irq, void *dev_id)
{ {
struct tpm_chip *chip = dev_id; struct tpm_chip *chip = dev_id;
...@@ -341,16 +293,10 @@ static irqreturn_t tpm_ioserirq_handler(int irq, void *dev_id) ...@@ -341,16 +293,10 @@ static irqreturn_t tpm_ioserirq_handler(int irq, void *dev_id)
disable_irq_nosync(tpm_dev->irq); disable_irq_nosync(tpm_dev->irq);
return IRQ_HANDLED; return IRQ_HANDLED;
} /* tpm_ioserirq_handler() */ }
/* /*
* st33zp24_send send TPM commands through the I2C bus. * send TPM commands through the I2C bus.
*
* @param: chip, the tpm_chip description as specified in driver/char/tpm/tpm.h
* @param: buf, the buffer to send.
* @param: count, the number of bytes to send.
* @return: In case of success the number of bytes sent.
* In other case, a < 0 value describing the issue.
*/ */
static int st33zp24_send(struct tpm_chip *chip, unsigned char *buf, static int st33zp24_send(struct tpm_chip *chip, unsigned char *buf,
size_t len) size_t len)
...@@ -431,14 +377,6 @@ static int st33zp24_send(struct tpm_chip *chip, unsigned char *buf, ...@@ -431,14 +377,6 @@ static int st33zp24_send(struct tpm_chip *chip, unsigned char *buf,
return ret; return ret;
} }
/*
* st33zp24_recv received TPM response through TPM phy.
* @param: chip, the tpm_chip description as specified in driver/char/tpm/tpm.h.
* @param: buf, the buffer to store datas.
* @param: count, the number of bytes to send.
* @return: In case of success the number of bytes received.
* In other case, a < 0 value describing the issue.
*/
static int st33zp24_recv(struct tpm_chip *chip, unsigned char *buf, static int st33zp24_recv(struct tpm_chip *chip, unsigned char *buf,
size_t count) size_t count)
{ {
...@@ -478,12 +416,6 @@ static int st33zp24_recv(struct tpm_chip *chip, unsigned char *buf, ...@@ -478,12 +416,6 @@ static int st33zp24_recv(struct tpm_chip *chip, unsigned char *buf,
return size; return size;
} }
/*
* st33zp24_req_canceled
* @param: chip, the tpm_chip description as specified in driver/char/tpm/tpm.h.
* @param: status, the TPM status.
* @return: Does TPM ready to compute a new command ? true.
*/
static bool st33zp24_req_canceled(struct tpm_chip *chip, u8 status) static bool st33zp24_req_canceled(struct tpm_chip *chip, u8 status)
{ {
return (status == TPM_STS_COMMAND_READY); return (status == TPM_STS_COMMAND_READY);
...@@ -501,11 +433,7 @@ static const struct tpm_class_ops st33zp24_tpm = { ...@@ -501,11 +433,7 @@ static const struct tpm_class_ops st33zp24_tpm = {
}; };
/* /*
* st33zp24_probe initialize the TPM device * initialize the TPM device
* @param: client, the i2c_client description (TPM I2C description).
* @param: id, the i2c_device_id struct.
* @return: 0 in case of success.
* -1 in other case.
*/ */
int st33zp24_probe(void *phy_id, const struct st33zp24_phy_ops *ops, int st33zp24_probe(void *phy_id, const struct st33zp24_phy_ops *ops,
struct device *dev, int irq, int io_lpcpd) struct device *dev, int irq, int io_lpcpd)
...@@ -583,11 +511,6 @@ int st33zp24_probe(void *phy_id, const struct st33zp24_phy_ops *ops, ...@@ -583,11 +511,6 @@ int st33zp24_probe(void *phy_id, const struct st33zp24_phy_ops *ops,
} }
EXPORT_SYMBOL(st33zp24_probe); EXPORT_SYMBOL(st33zp24_probe);
/*
* st33zp24_remove remove the TPM device
* @param: tpm_data, the tpm phy.
* @return: 0 in case of success.
*/
int st33zp24_remove(struct tpm_chip *chip) int st33zp24_remove(struct tpm_chip *chip)
{ {
tpm_chip_unregister(chip); tpm_chip_unregister(chip);
...@@ -596,12 +519,6 @@ int st33zp24_remove(struct tpm_chip *chip) ...@@ -596,12 +519,6 @@ int st33zp24_remove(struct tpm_chip *chip)
EXPORT_SYMBOL(st33zp24_remove); EXPORT_SYMBOL(st33zp24_remove);
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
/*
* st33zp24_pm_suspend suspend the TPM device
* @param: tpm_data, the tpm phy.
* @param: mesg, the power management message.
* @return: 0 in case of success.
*/
int st33zp24_pm_suspend(struct device *dev) int st33zp24_pm_suspend(struct device *dev)
{ {
struct tpm_chip *chip = dev_get_drvdata(dev); struct tpm_chip *chip = dev_get_drvdata(dev);
...@@ -615,14 +532,9 @@ int st33zp24_pm_suspend(struct device *dev) ...@@ -615,14 +532,9 @@ int st33zp24_pm_suspend(struct device *dev)
ret = tpm_pm_suspend(dev); ret = tpm_pm_suspend(dev);
return ret; return ret;
} /* st33zp24_pm_suspend() */ }
EXPORT_SYMBOL(st33zp24_pm_suspend); EXPORT_SYMBOL(st33zp24_pm_suspend);
/*
* st33zp24_pm_resume resume the TPM device
* @param: tpm_data, the tpm phy.
* @return: 0 in case of success.
*/
int st33zp24_pm_resume(struct device *dev) int st33zp24_pm_resume(struct device *dev)
{ {
struct tpm_chip *chip = dev_get_drvdata(dev); struct tpm_chip *chip = dev_get_drvdata(dev);
...@@ -640,7 +552,7 @@ int st33zp24_pm_resume(struct device *dev) ...@@ -640,7 +552,7 @@ int st33zp24_pm_resume(struct device *dev)
tpm1_do_selftest(chip); tpm1_do_selftest(chip);
} }
return ret; return ret;
} /* st33zp24_pm_resume() */ }
EXPORT_SYMBOL(st33zp24_pm_resume); EXPORT_SYMBOL(st33zp24_pm_resume);
#endif #endif
......
...@@ -444,7 +444,7 @@ static int tpm_add_char_device(struct tpm_chip *chip) ...@@ -444,7 +444,7 @@ static int tpm_add_char_device(struct tpm_chip *chip)
return rc; return rc;
} }
if (chip->flags & TPM_CHIP_FLAG_TPM2) { if (chip->flags & TPM_CHIP_FLAG_TPM2 && !tpm_is_firmware_upgrade(chip)) {
rc = cdev_device_add(&chip->cdevs, &chip->devs); rc = cdev_device_add(&chip->cdevs, &chip->devs);
if (rc) { if (rc) {
dev_err(&chip->devs, dev_err(&chip->devs,
...@@ -474,6 +474,13 @@ static void tpm_del_char_device(struct tpm_chip *chip) ...@@ -474,6 +474,13 @@ static void tpm_del_char_device(struct tpm_chip *chip)
/* Make the driver uncallable. */ /* Make the driver uncallable. */
down_write(&chip->ops_sem); down_write(&chip->ops_sem);
/*
* Check if chip->ops is still valid: In case that the controller
* drivers shutdown handler unregisters the controller in its
* shutdown handler we are called twice and chip->ops to NULL.
*/
if (chip->ops) {
if (chip->flags & TPM_CHIP_FLAG_TPM2) { if (chip->flags & TPM_CHIP_FLAG_TPM2) {
if (!tpm_chip_start(chip)) { if (!tpm_chip_start(chip)) {
tpm2_shutdown(chip, TPM2_SU_CLEAR); tpm2_shutdown(chip, TPM2_SU_CLEAR);
...@@ -481,6 +488,7 @@ static void tpm_del_char_device(struct tpm_chip *chip) ...@@ -481,6 +488,7 @@ static void tpm_del_char_device(struct tpm_chip *chip)
} }
} }
chip->ops = NULL; chip->ops = NULL;
}
up_write(&chip->ops_sem); up_write(&chip->ops_sem);
} }
...@@ -488,7 +496,8 @@ static void tpm_del_legacy_sysfs(struct tpm_chip *chip) ...@@ -488,7 +496,8 @@ static void tpm_del_legacy_sysfs(struct tpm_chip *chip)
{ {
struct attribute **i; struct attribute **i;
if (chip->flags & (TPM_CHIP_FLAG_TPM2 | TPM_CHIP_FLAG_VIRTUAL)) if (chip->flags & (TPM_CHIP_FLAG_TPM2 | TPM_CHIP_FLAG_VIRTUAL) ||
tpm_is_firmware_upgrade(chip))
return; return;
sysfs_remove_link(&chip->dev.parent->kobj, "ppi"); sysfs_remove_link(&chip->dev.parent->kobj, "ppi");
...@@ -506,7 +515,8 @@ static int tpm_add_legacy_sysfs(struct tpm_chip *chip) ...@@ -506,7 +515,8 @@ static int tpm_add_legacy_sysfs(struct tpm_chip *chip)
struct attribute **i; struct attribute **i;
int rc; int rc;
if (chip->flags & (TPM_CHIP_FLAG_TPM2 | TPM_CHIP_FLAG_VIRTUAL)) if (chip->flags & (TPM_CHIP_FLAG_TPM2 | TPM_CHIP_FLAG_VIRTUAL) ||
tpm_is_firmware_upgrade(chip))
return 0; return 0;
rc = compat_only_sysfs_link_entry_to_kobj( rc = compat_only_sysfs_link_entry_to_kobj(
...@@ -536,7 +546,7 @@ static int tpm_hwrng_read(struct hwrng *rng, void *data, size_t max, bool wait) ...@@ -536,7 +546,7 @@ static int tpm_hwrng_read(struct hwrng *rng, void *data, size_t max, bool wait)
static int tpm_add_hwrng(struct tpm_chip *chip) static int tpm_add_hwrng(struct tpm_chip *chip)
{ {
if (!IS_ENABLED(CONFIG_HW_RANDOM_TPM)) if (!IS_ENABLED(CONFIG_HW_RANDOM_TPM) || tpm_is_firmware_upgrade(chip))
return 0; return 0;
snprintf(chip->hwrng_name, sizeof(chip->hwrng_name), snprintf(chip->hwrng_name, sizeof(chip->hwrng_name),
...@@ -550,6 +560,9 @@ static int tpm_get_pcr_allocation(struct tpm_chip *chip) ...@@ -550,6 +560,9 @@ static int tpm_get_pcr_allocation(struct tpm_chip *chip)
{ {
int rc; int rc;
if (tpm_is_firmware_upgrade(chip))
return 0;
rc = (chip->flags & TPM_CHIP_FLAG_TPM2) ? rc = (chip->flags & TPM_CHIP_FLAG_TPM2) ?
tpm2_get_pcr_allocation(chip) : tpm2_get_pcr_allocation(chip) :
tpm1_get_pcr_allocation(chip); tpm1_get_pcr_allocation(chip);
...@@ -612,7 +625,7 @@ int tpm_chip_register(struct tpm_chip *chip) ...@@ -612,7 +625,7 @@ int tpm_chip_register(struct tpm_chip *chip)
return 0; return 0;
out_hwrng: out_hwrng:
if (IS_ENABLED(CONFIG_HW_RANDOM_TPM)) if (IS_ENABLED(CONFIG_HW_RANDOM_TPM) && !tpm_is_firmware_upgrade(chip))
hwrng_unregister(&chip->hwrng); hwrng_unregister(&chip->hwrng);
out_ppi: out_ppi:
tpm_bios_log_teardown(chip); tpm_bios_log_teardown(chip);
...@@ -637,10 +650,10 @@ EXPORT_SYMBOL_GPL(tpm_chip_register); ...@@ -637,10 +650,10 @@ EXPORT_SYMBOL_GPL(tpm_chip_register);
void tpm_chip_unregister(struct tpm_chip *chip) void tpm_chip_unregister(struct tpm_chip *chip)
{ {
tpm_del_legacy_sysfs(chip); tpm_del_legacy_sysfs(chip);
if (IS_ENABLED(CONFIG_HW_RANDOM_TPM)) if (IS_ENABLED(CONFIG_HW_RANDOM_TPM) && !tpm_is_firmware_upgrade(chip))
hwrng_unregister(&chip->hwrng); hwrng_unregister(&chip->hwrng);
tpm_bios_log_teardown(chip); tpm_bios_log_teardown(chip);
if (chip->flags & TPM_CHIP_FLAG_TPM2) if (chip->flags & TPM_CHIP_FLAG_TPM2 && !tpm_is_firmware_upgrade(chip))
cdev_device_del(&chip->cdevs, &chip->devs); cdev_device_del(&chip->cdevs, &chip->devs);
tpm_del_char_device(chip); tpm_del_char_device(chip);
} }
......
...@@ -480,6 +480,9 @@ void tpm_sysfs_add_device(struct tpm_chip *chip) ...@@ -480,6 +480,9 @@ void tpm_sysfs_add_device(struct tpm_chip *chip)
WARN_ON(chip->groups_cnt != 0); WARN_ON(chip->groups_cnt != 0);
if (tpm_is_firmware_upgrade(chip))
return;
if (chip->flags & TPM_CHIP_FLAG_TPM2) if (chip->flags & TPM_CHIP_FLAG_TPM2)
chip->groups[chip->groups_cnt++] = &tpm2_dev_group; chip->groups[chip->groups_cnt++] = &tpm2_dev_group;
else else
......
...@@ -745,6 +745,12 @@ int tpm2_auto_startup(struct tpm_chip *chip) ...@@ -745,6 +745,12 @@ int tpm2_auto_startup(struct tpm_chip *chip)
rc = tpm2_get_cc_attrs_tbl(chip); rc = tpm2_get_cc_attrs_tbl(chip);
out: out:
if (rc == TPM2_RC_UPGRADE) {
dev_info(&chip->dev, "TPM in field upgrade mode, requires firmware upgrade\n");
chip->flags |= TPM_CHIP_FLAG_FIRMWARE_UPGRADE;
rc = 0;
}
if (rc > 0) if (rc > 0)
rc = -ENODEV; rc = -ENODEV;
return rc; return rc;
......
...@@ -950,9 +950,11 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, ...@@ -950,9 +950,11 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
priv->timeout_max = TPM_TIMEOUT_USECS_MAX; priv->timeout_max = TPM_TIMEOUT_USECS_MAX;
priv->phy_ops = phy_ops; priv->phy_ops = phy_ops;
dev_set_drvdata(&chip->dev, priv);
rc = tpm_tis_read32(priv, TPM_DID_VID(0), &vendor); rc = tpm_tis_read32(priv, TPM_DID_VID(0), &vendor);
if (rc < 0) if (rc < 0)
goto out_err; return rc;
priv->manufacturer_id = vendor; priv->manufacturer_id = vendor;
...@@ -962,8 +964,6 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, ...@@ -962,8 +964,6 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
priv->timeout_max = TIS_TIMEOUT_MAX_ATML; priv->timeout_max = TIS_TIMEOUT_MAX_ATML;
} }
dev_set_drvdata(&chip->dev, priv);
if (is_bsw()) { if (is_bsw()) {
priv->ilb_base_addr = ioremap(INTEL_LEGACY_BLK_BASE_ADDR, priv->ilb_base_addr = ioremap(INTEL_LEGACY_BLK_BASE_ADDR,
ILB_REMAP_SIZE); ILB_REMAP_SIZE);
...@@ -994,7 +994,15 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, ...@@ -994,7 +994,15 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
intmask |= TPM_INTF_CMD_READY_INT | TPM_INTF_LOCALITY_CHANGE_INT | intmask |= TPM_INTF_CMD_READY_INT | TPM_INTF_LOCALITY_CHANGE_INT |
TPM_INTF_DATA_AVAIL_INT | TPM_INTF_STS_VALID_INT; TPM_INTF_DATA_AVAIL_INT | TPM_INTF_STS_VALID_INT;
intmask &= ~TPM_GLOBAL_INT_ENABLE; intmask &= ~TPM_GLOBAL_INT_ENABLE;
rc = request_locality(chip, 0);
if (rc < 0) {
rc = -ENODEV;
goto out_err;
}
tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask); tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask);
release_locality(chip, 0);
rc = tpm_chip_start(chip); rc = tpm_chip_start(chip);
if (rc) if (rc)
......
...@@ -628,6 +628,19 @@ static bool tpm_cr50_i2c_req_canceled(struct tpm_chip *chip, u8 status) ...@@ -628,6 +628,19 @@ static bool tpm_cr50_i2c_req_canceled(struct tpm_chip *chip, u8 status)
return status == TPM_STS_COMMAND_READY; return status == TPM_STS_COMMAND_READY;
} }
static bool tpm_cr50_i2c_is_firmware_power_managed(struct device *dev)
{
u8 val;
int ret;
/* This flag should default true when the device property is not present */
ret = device_property_read_u8(dev, "firmware-power-managed", &val);
if (ret)
return true;
return val;
}
static const struct tpm_class_ops cr50_i2c = { static const struct tpm_class_ops cr50_i2c = {
.flags = TPM_OPS_AUTO_STARTUP, .flags = TPM_OPS_AUTO_STARTUP,
.status = &tpm_cr50_i2c_tis_status, .status = &tpm_cr50_i2c_tis_status,
...@@ -686,6 +699,7 @@ static int tpm_cr50_i2c_probe(struct i2c_client *client) ...@@ -686,6 +699,7 @@ static int tpm_cr50_i2c_probe(struct i2c_client *client)
/* cr50 is a TPM 2.0 chip */ /* cr50 is a TPM 2.0 chip */
chip->flags |= TPM_CHIP_FLAG_TPM2; chip->flags |= TPM_CHIP_FLAG_TPM2;
if (tpm_cr50_i2c_is_firmware_power_managed(dev))
chip->flags |= TPM_CHIP_FLAG_FIRMWARE_POWER_MANAGED; chip->flags |= TPM_CHIP_FLAG_FIRMWARE_POWER_MANAGED;
/* Default timeouts */ /* Default timeouts */
......
...@@ -36,6 +36,9 @@ ...@@ -36,6 +36,9 @@
#define TPM_CR50_FW_VER(l) (0x0f90 | ((l) << 12)) #define TPM_CR50_FW_VER(l) (0x0f90 | ((l) << 12))
#define TPM_CR50_MAX_FW_VER_LEN 64 #define TPM_CR50_MAX_FW_VER_LEN 64
/* Default quality for hwrng. */
#define TPM_CR50_DEFAULT_RNG_QUALITY 700
struct cr50_spi_phy { struct cr50_spi_phy {
struct tpm_tis_spi_phy spi_phy; struct tpm_tis_spi_phy spi_phy;
...@@ -182,6 +185,19 @@ static int cr50_spi_flow_control(struct tpm_tis_spi_phy *phy, ...@@ -182,6 +185,19 @@ static int cr50_spi_flow_control(struct tpm_tis_spi_phy *phy,
return 0; return 0;
} }
static bool tpm_cr50_spi_is_firmware_power_managed(struct device *dev)
{
u8 val;
int ret;
/* This flag should default true when the device property is not present */
ret = device_property_read_u8(dev, "firmware-power-managed", &val);
if (ret)
return true;
return val;
}
static int tpm_tis_spi_cr50_transfer(struct tpm_tis_data *data, u32 addr, u16 len, static int tpm_tis_spi_cr50_transfer(struct tpm_tis_data *data, u32 addr, u16 len,
u8 *in, const u8 *out) u8 *in, const u8 *out)
{ {
...@@ -264,6 +280,7 @@ int cr50_spi_probe(struct spi_device *spi) ...@@ -264,6 +280,7 @@ int cr50_spi_probe(struct spi_device *spi)
phy = &cr50_phy->spi_phy; phy = &cr50_phy->spi_phy;
phy->flow_control = cr50_spi_flow_control; phy->flow_control = cr50_spi_flow_control;
phy->wake_after = jiffies; phy->wake_after = jiffies;
phy->priv.rng_quality = TPM_CR50_DEFAULT_RNG_QUALITY;
init_completion(&phy->ready); init_completion(&phy->ready);
cr50_phy->access_delay = CR50_NOIRQ_ACCESS_DELAY; cr50_phy->access_delay = CR50_NOIRQ_ACCESS_DELAY;
...@@ -305,6 +322,7 @@ int cr50_spi_probe(struct spi_device *spi) ...@@ -305,6 +322,7 @@ int cr50_spi_probe(struct spi_device *spi)
cr50_print_fw_version(&phy->priv); cr50_print_fw_version(&phy->priv);
chip = dev_get_drvdata(&spi->dev); chip = dev_get_drvdata(&spi->dev);
if (tpm_cr50_spi_is_firmware_power_managed(&spi->dev))
chip->flags |= TPM_CHIP_FLAG_FIRMWARE_POWER_MANAGED; chip->flags |= TPM_CHIP_FLAG_FIRMWARE_POWER_MANAGED;
return 0; return 0;
......
...@@ -36,7 +36,7 @@ extern void public_key_free(struct public_key *key); ...@@ -36,7 +36,7 @@ extern void public_key_free(struct public_key *key);
* Public key cryptography signature data * Public key cryptography signature data
*/ */
struct public_key_signature { struct public_key_signature {
struct asymmetric_key_id *auth_ids[2]; struct asymmetric_key_id *auth_ids[3];
u8 *s; /* Signature */ u8 *s; /* Signature */
u8 *digest; u8 *digest;
u32 s_size; /* Number of bytes in signature */ u32 s_size; /* Number of bytes in signature */
......
...@@ -53,7 +53,7 @@ struct asymmetric_key_id { ...@@ -53,7 +53,7 @@ struct asymmetric_key_id {
}; };
struct asymmetric_key_ids { struct asymmetric_key_ids {
void *id[2]; void *id[3];
}; };
extern bool asymmetric_key_id_same(const struct asymmetric_key_id *kid1, extern bool asymmetric_key_id_same(const struct asymmetric_key_id *kid1,
...@@ -81,6 +81,7 @@ const struct public_key *asymmetric_key_public_key(const struct key *key) ...@@ -81,6 +81,7 @@ const struct public_key *asymmetric_key_public_key(const struct key *key)
extern struct key *find_asymmetric_key(struct key *keyring, extern struct key *find_asymmetric_key(struct key *keyring,
const struct asymmetric_key_id *id_0, const struct asymmetric_key_id *id_0,
const struct asymmetric_key_id *id_1, const struct asymmetric_key_id *id_1,
const struct asymmetric_key_id *id_2,
bool partial); bool partial);
/* /*
......
...@@ -207,6 +207,7 @@ enum tpm2_return_codes { ...@@ -207,6 +207,7 @@ enum tpm2_return_codes {
TPM2_RC_INITIALIZE = 0x0100, /* RC_VER1 */ TPM2_RC_INITIALIZE = 0x0100, /* RC_VER1 */
TPM2_RC_FAILURE = 0x0101, TPM2_RC_FAILURE = 0x0101,
TPM2_RC_DISABLED = 0x0120, TPM2_RC_DISABLED = 0x0120,
TPM2_RC_UPGRADE = 0x012D,
TPM2_RC_COMMAND_CODE = 0x0143, TPM2_RC_COMMAND_CODE = 0x0143,
TPM2_RC_TESTING = 0x090A, /* RC_WARN */ TPM2_RC_TESTING = 0x090A, /* RC_WARN */
TPM2_RC_REFERENCE_H0 = 0x0910, TPM2_RC_REFERENCE_H0 = 0x0910,
...@@ -278,6 +279,7 @@ enum tpm_chip_flags { ...@@ -278,6 +279,7 @@ enum tpm_chip_flags {
TPM_CHIP_FLAG_HAVE_TIMEOUTS = BIT(4), TPM_CHIP_FLAG_HAVE_TIMEOUTS = BIT(4),
TPM_CHIP_FLAG_ALWAYS_POWERED = BIT(5), TPM_CHIP_FLAG_ALWAYS_POWERED = BIT(5),
TPM_CHIP_FLAG_FIRMWARE_POWER_MANAGED = BIT(6), TPM_CHIP_FLAG_FIRMWARE_POWER_MANAGED = BIT(6),
TPM_CHIP_FLAG_FIRMWARE_UPGRADE = BIT(7),
}; };
#define to_tpm_chip(d) container_of(d, struct tpm_chip, dev) #define to_tpm_chip(d) container_of(d, struct tpm_chip, dev)
...@@ -399,6 +401,14 @@ static inline void tpm_buf_append_u32(struct tpm_buf *buf, const u32 value) ...@@ -399,6 +401,14 @@ static inline void tpm_buf_append_u32(struct tpm_buf *buf, const u32 value)
tpm_buf_append(buf, (u8 *) &value2, 4); tpm_buf_append(buf, (u8 *) &value2, 4);
} }
/*
* Check if TPM device is in the firmware upgrade mode.
*/
static inline bool tpm_is_firmware_upgrade(struct tpm_chip *chip)
{
return chip->flags & TPM_CHIP_FLAG_FIRMWARE_UPGRADE;
}
static inline u32 tpm2_rc_value(u32 rc) static inline u32 tpm2_rc_value(u32 rc)
{ {
return (rc & BIT(7)) ? rc & 0xff : rc; return (rc & BIT(7)) ? rc & 0xff : rc;
......
...@@ -164,8 +164,6 @@ asn1_encode_oid(unsigned char *data, const unsigned char *end_data, ...@@ -164,8 +164,6 @@ asn1_encode_oid(unsigned char *data, const unsigned char *end_data,
data_len -= 3; data_len -= 3;
ret = 0;
for (i = 2; i < oid_len; i++) { for (i = 2; i < oid_len; i++) {
ret = asn1_encode_oid_digit(&d, &data_len, oid[i]); ret = asn1_encode_oid_digit(&d, &data_len, oid[i]);
if (ret < 0) if (ret < 0)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment