Message ID | 20200507231147.27025-4-James.Bottomley@HansenPartnership.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | TPM 2.0 trusted keys with attached policy | expand |
On Thu, 2020-05-07 at 16:11 -0700, James Bottomley wrote: > In TPM 1.2 an authorization was a 20 byte number. The spec actually > recommended you to hash variable length passwords and use the sha1 > hash as the authorization. Because the spec doesn't require this > hashing, the current authorization for trusted keys is a 40 digit hex > number. For TPM 2.0 the spec allows the passing in of variable length > passwords and passphrases directly, so we should allow that in trusted > keys for ease of use. Update the 'blobauth' parameter to take this > into account, so we can now use plain text passwords for the keys. > > so before > > keyctl add trusted kmk "new 32 blobauth=f572d396fae9206628714fb2ce00f72e94f2258f" > > after we will accept both the old hex sha1 form as well as a new > directly supplied password: > > keyctl add trusted kmk "new 32 blobauth=hello keyhandle=81000001" > > Since a sha1 hex code must be exactly 40 bytes long and a direct > password must be 20 or less, we use the length as the discriminator > for which form is input. > > Note this is both and enhancement and a potential bug fix. The TPM > 2.0 spec requires us to strip leading zeros, meaning empyty > authorization is a zero length HMAC whereas we're currently passing in > 20 bytes of zeros. A lot of TPMs simply accept this as OK, but the > Microsoft TPM emulator rejects it with TPM_RC_BAD_AUTH, so this patch > makes the Microsoft TPM emulator work with trusted keys. > > Fixes: 0fe5480303a1 ("keys, trusted: seal/unseal with TPM 2.0 chips") > Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com> > Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> Have not checked yet the tail. Probably won't check before PR for v5.8 is out. Just wondering would it hurt to merge everything up until this patch? /Jarkko
On Thu, 2020-05-14 at 04:11 +0300, Jarkko Sakkinen wrote: > On Thu, 2020-05-07 at 16:11 -0700, James Bottomley wrote: > > In TPM 1.2 an authorization was a 20 byte number. The spec actually > > recommended you to hash variable length passwords and use the sha1 > > hash as the authorization. Because the spec doesn't require this > > hashing, the current authorization for trusted keys is a 40 digit hex > > number. For TPM 2.0 the spec allows the passing in of variable length > > passwords and passphrases directly, so we should allow that in trusted > > keys for ease of use. Update the 'blobauth' parameter to take this > > into account, so we can now use plain text passwords for the keys. > > > > so before > > > > keyctl add trusted kmk "new 32 blobauth=f572d396fae9206628714fb2ce00f72e94f2258f" > > > > after we will accept both the old hex sha1 form as well as a new > > directly supplied password: > > > > keyctl add trusted kmk "new 32 blobauth=hello keyhandle=81000001" > > > > Since a sha1 hex code must be exactly 40 bytes long and a direct > > password must be 20 or less, we use the length as the discriminator > > for which form is input. > > > > Note this is both and enhancement and a potential bug fix. The TPM > > 2.0 spec requires us to strip leading zeros, meaning empyty > > authorization is a zero length HMAC whereas we're currently passing in > > 20 bytes of zeros. A lot of TPMs simply accept this as OK, but the > > Microsoft TPM emulator rejects it with TPM_RC_BAD_AUTH, so this patch > > makes the Microsoft TPM emulator work with trusted keys. > > > > Fixes: 0fe5480303a1 ("keys, trusted: seal/unseal with TPM 2.0 chips") > > Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com> > > Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> > > Have not checked yet the tail. Probably won't check before PR for v5.8 > is out. > > Just wondering would it hurt to merge everything up until this patch? I.e. could land it also to the release. /Jarkko
On Thu, 2020-05-14 at 04:12 +0300, Jarkko Sakkinen wrote: > On Thu, 2020-05-14 at 04:11 +0300, Jarkko Sakkinen wrote: > > On Thu, 2020-05-07 at 16:11 -0700, James Bottomley wrote: > > > In TPM 1.2 an authorization was a 20 byte number. The spec > > > actually recommended you to hash variable length passwords and > > > use the sha1 hash as the authorization. Because the spec doesn't > > > require this hashing, the current authorization for trusted keys > > > is a 40 digit hex number. For TPM 2.0 the spec allows the > > > passing in of variable length passwords and passphrases directly, > > > so we should allow that in trusted keys for ease of use. Update > > > the 'blobauth' parameter to take this into account, so we can now > > > use plain text passwords for the keys. > > > > > > so before > > > > > > keyctl add trusted kmk "new 32 > > > blobauth=f572d396fae9206628714fb2ce00f72e94f2258f" > > > > > > after we will accept both the old hex sha1 form as well as a new > > > directly supplied password: > > > > > > keyctl add trusted kmk "new 32 blobauth=hello keyhandle=81000001" > > > > > > Since a sha1 hex code must be exactly 40 bytes long and a direct > > > password must be 20 or less, we use the length as the > > > discriminator for which form is input. > > > > > > Note this is both and enhancement and a potential bug fix. The > > > TPM 2.0 spec requires us to strip leading zeros, meaning empyty > > > authorization is a zero length HMAC whereas we're currently > > > passing in 20 bytes of zeros. A lot of TPMs simply accept this > > > as OK, but the Microsoft TPM emulator rejects it with > > > TPM_RC_BAD_AUTH, so this patch makes the Microsoft TPM emulator > > > work with trusted keys. > > > > > > Fixes: 0fe5480303a1 ("keys, trusted: seal/unseal with TPM 2.0 > > > chips") > > > Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership > > > .com> > > > Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> > > > > Have not checked yet the tail. Probably won't check before PR for > > v5.8 is out. > > > > Just wondering would it hurt to merge everything up until this > > patch? Everything would be OK if you applied 1, 2 and 3. Except we'd have an ASN.1 API in the tree with no consumers, which excites some people. > I.e. could land it also to the release. That would likely be fine and should satisfy the API with no consumers issue. James
On Wed, 2020-05-13 at 18:41 -0700, James Bottomley wrote: > On Thu, 2020-05-14 at 04:12 +0300, Jarkko Sakkinen wrote: > > On Thu, 2020-05-14 at 04:11 +0300, Jarkko Sakkinen wrote: > > > On Thu, 2020-05-07 at 16:11 -0700, James Bottomley wrote: > > > > In TPM 1.2 an authorization was a 20 byte number. The spec > > > > actually recommended you to hash variable length passwords and > > > > use the sha1 hash as the authorization. Because the spec doesn't > > > > require this hashing, the current authorization for trusted keys > > > > is a 40 digit hex number. For TPM 2.0 the spec allows the > > > > passing in of variable length passwords and passphrases directly, > > > > so we should allow that in trusted keys for ease of use. Update > > > > the 'blobauth' parameter to take this into account, so we can now > > > > use plain text passwords for the keys. > > > > > > > > so before > > > > > > > > keyctl add trusted kmk "new 32 > > > > blobauth=f572d396fae9206628714fb2ce00f72e94f2258f" > > > > > > > > after we will accept both the old hex sha1 form as well as a new > > > > directly supplied password: > > > > > > > > keyctl add trusted kmk "new 32 blobauth=hello keyhandle=81000001" > > > > > > > > Since a sha1 hex code must be exactly 40 bytes long and a direct > > > > password must be 20 or less, we use the length as the > > > > discriminator for which form is input. > > > > > > > > Note this is both and enhancement and a potential bug fix. The > > > > TPM 2.0 spec requires us to strip leading zeros, meaning empyty > > > > authorization is a zero length HMAC whereas we're currently > > > > passing in 20 bytes of zeros. A lot of TPMs simply accept this > > > > as OK, but the Microsoft TPM emulator rejects it with > > > > TPM_RC_BAD_AUTH, so this patch makes the Microsoft TPM emulator > > > > work with trusted keys. > > > > > > > > Fixes: 0fe5480303a1 ("keys, trusted: seal/unseal with TPM 2.0 > > > > chips") > > > > Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership > > > > .com> > > > > Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> > > > > > > Have not checked yet the tail. Probably won't check before PR for > > > v5.8 is out. > > > > > > Just wondering would it hurt to merge everything up until this > > > patch? > > Everything would be OK if you applied 1, 2 and 3. Except we'd have an > ASN.1 API in the tree with no consumers, which excites some people. > > > I.e. could land it also to the release. > > That would likely be fine and should satisfy the API with no consumers > issue. Hmm. Right, it does not sense to merge unused API. I'd like to still pick this patch (3/8) but you need to fix these first: WARNING: Possible unwrapped commit description (prefer a maximum 75 chars per line) #17: keyctl add trusted kmk "new 32 blobauth=f572d396fae9206628714fb2ce00f72e94f2258f" WARNING: line over 80 characters #89: FILE: security/keys/trusted-keys/trusted_tpm1.c:801: + if (tpm2 && opt->blobauth_len <= sizeof(opt->blobauth)) { WARNING: line over 80 characters #111: FILE: security/keys/trusted-keys/trusted_tpm2.c:94: + tpm_buf_append_u16(&buf, 4 + options->blobauth_len + payload->key_len + 1); The best way is probably to encapsulate into helper function. It is more or less a sign that the code is too complicated to live inside a switch-case statement. Can you do that and send it as a separate patch? /Jarkko
diff --git a/include/keys/trusted-type.h b/include/keys/trusted-type.h index a94c03a61d8f..b2ed3481c6a0 100644 --- a/include/keys/trusted-type.h +++ b/include/keys/trusted-type.h @@ -30,6 +30,7 @@ struct trusted_key_options { uint16_t keytype; uint32_t keyhandle; unsigned char keyauth[TPM_DIGEST_SIZE]; + uint32_t blobauth_len; unsigned char blobauth[TPM_DIGEST_SIZE]; uint32_t pcrinfo_len; unsigned char pcrinfo[MAX_PCRINFO_SIZE]; diff --git a/security/keys/trusted-keys/trusted_tpm1.c b/security/keys/trusted-keys/trusted_tpm1.c index 8001ab07e63b..3b8fa7df0d27 100644 --- a/security/keys/trusted-keys/trusted_tpm1.c +++ b/security/keys/trusted-keys/trusted_tpm1.c @@ -781,13 +781,33 @@ static int getoptions(char *c, struct trusted_key_payload *pay, return -EINVAL; break; case Opt_blobauth: - if (strlen(args[0].from) != 2 * SHA1_DIGEST_SIZE) - return -EINVAL; - res = hex2bin(opt->blobauth, args[0].from, - SHA1_DIGEST_SIZE); - if (res < 0) - return -EINVAL; + /* + * TPM 1.2 authorizations are sha1 hashes passed in as + * hex strings. TPM 2.0 authorizations are simple + * passwords (although it can take a hash as well) + */ + opt->blobauth_len = strlen(args[0].from); + + if (opt->blobauth_len == 2 * TPM_DIGEST_SIZE) { + res = hex2bin(opt->blobauth, args[0].from, + TPM_DIGEST_SIZE); + if (res < 0) + return -EINVAL; + + opt->blobauth_len = TPM_DIGEST_SIZE; + return 0; + } + + if (tpm2 && opt->blobauth_len <= sizeof(opt->blobauth)) { + memcpy(opt->blobauth, args[0].from, + opt->blobauth_len); + return 0; + } + + return -EINVAL; + break; + case Opt_migratable: if (*args[0].from == '0') pay->migratable = 0; diff --git a/security/keys/trusted-keys/trusted_tpm2.c b/security/keys/trusted-keys/trusted_tpm2.c index 08ec7f48f01d..b4a5058107c2 100644 --- a/security/keys/trusted-keys/trusted_tpm2.c +++ b/security/keys/trusted-keys/trusted_tpm2.c @@ -91,10 +91,12 @@ int tpm2_seal_trusted(struct tpm_chip *chip, TPM_DIGEST_SIZE); /* sensitive */ - tpm_buf_append_u16(&buf, 4 + TPM_DIGEST_SIZE + payload->key_len + 1); + tpm_buf_append_u16(&buf, 4 + options->blobauth_len + payload->key_len + 1); + + tpm_buf_append_u16(&buf, options->blobauth_len); + if (options->blobauth_len) + tpm_buf_append(&buf, options->blobauth, options->blobauth_len); - tpm_buf_append_u16(&buf, TPM_DIGEST_SIZE); - tpm_buf_append(&buf, options->blobauth, TPM_DIGEST_SIZE); tpm_buf_append_u16(&buf, payload->key_len + 1); tpm_buf_append(&buf, payload->key, payload->key_len); tpm_buf_append_u8(&buf, payload->migratable); @@ -258,7 +260,7 @@ static int tpm2_unseal_cmd(struct tpm_chip *chip, NULL /* nonce */, 0, TPM2_SA_CONTINUE_SESSION, options->blobauth /* hmac */, - TPM_DIGEST_SIZE); + options->blobauth_len); rc = tpm_send(chip, buf.data, tpm_buf_length(&buf)); if (rc > 0)