[PATCH v2 0/3] TPM 2.0 trusted key features for v4.5
These are the remaining features to enable trusted keys for TPM 2.0 that were not finished by the v4.4 merge window. These patches enable authorization policy based sealing (like using PCRs together with a password for example or something more complicated) with a user selected hash algorithm. Jarkko Sakkinen (3): keys, trusted: fix: *do not* allow duplicate key options keys, trusted: select hash algorithm for TPM2 chips keys, trusted: seal with a TPM2 authorization policy Documentation/security/keys-trusted-encrypted.txt | 31 +++- crypto/hash_info.c| 2 + drivers/char/tpm/tpm.h| 10 ++-- drivers/char/tpm/tpm2-cmd.c | 60 --- include/crypto/hash_info.h| 3 ++ include/keys/trusted-type.h | 5 ++ include/uapi/linux/hash_info.h| 1 + security/keys/Kconfig | 1 + security/keys/trusted.c | 56 - 9 files changed, 147 insertions(+), 22 deletions(-) -- 2.5.0 -- To unsubscribe from this list: send the line "unsubscribe linux-security-module" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 3/3] keys, trusted: seal with a TPM2 authorization policy
TPM2 supports authorization policies, which are essentially combinational logic statements repsenting the conditions where the data can be unsealed based on the TPM state. This patch enables to use authorization policies to seal trusted keys. Two following new options have been added for trusted keys: * 'policydigest=': provide an auth policy digest for sealing. * 'policyhandle=': provide a policy session handle for unsealing. If 'hash=' option is supplied after 'policydigest=' option, this will result an error because the state of the option would become mixed. Signed-off-by: Jarkko SakkinenTested-by: Colin Ian King --- Documentation/security/keys-trusted-encrypted.txt | 34 +-- drivers/char/tpm/tpm2-cmd.c | 24 +--- include/keys/trusted-type.h | 4 +++ security/keys/trusted.c | 26 + 4 files changed, 70 insertions(+), 18 deletions(-) diff --git a/Documentation/security/keys-trusted-encrypted.txt b/Documentation/security/keys-trusted-encrypted.txt index fd2565b..324ddf5 100644 --- a/Documentation/security/keys-trusted-encrypted.txt +++ b/Documentation/security/keys-trusted-encrypted.txt @@ -27,20 +27,26 @@ Usage: keyctl print keyid options: - keyhandle= ascii hex value of sealing key default 0x4000 (SRK) - keyauth= ascii hex auth for sealing key default 0x00...i - (40 ascii zeros) - blobauth= ascii hex auth for sealed data default 0x00... - (40 ascii zeros) - blobauth= ascii hex auth for sealed data default 0x00... - (40 ascii zeros) - pcrinfo= ascii hex of PCR_INFO or PCR_INFO_LONG (no default) - pcrlock= pcr number to be extended to "lock" blob - migratable= 0|1 indicating permission to reseal to new PCR values, - default 1 (resealing allowed) - hash= hash algorithm name as a string. For TPM 1.x the only - allowed value is sha1. For TPM 2.x the allowed values - are sha1, sha256, sha384, sha512 and sm3-256. + keyhandle=ascii hex value of sealing key default 0x4000 (SRK) + keyauth= ascii hex auth for sealing key default 0x00...i + (40 ascii zeros) + blobauth= ascii hex auth for sealed data default 0x00... + (40 ascii zeros) + blobauth= ascii hex auth for sealed data default 0x00... + (40 ascii zeros) + pcrinfo= ascii hex of PCR_INFO or PCR_INFO_LONG (no default) + pcrlock= pcr number to be extended to "lock" blob + migratable= 0|1 indicating permission to reseal to new PCR values, + default 1 (resealing allowed) + hash= hash algorithm name as a string. For TPM 1.x the only + allowed value is sha1. For TPM 2.x the allowed values + are sha1, sha256, sha384, sha512 and sm3-256. + policydigest= digest for the authorization policy. must be calculated + with the same hash algorithm as specified by the 'hash=' + option. + policyhandle= handle to an authorization policy session that defines the + same policy and with the same hash algorithm as was used to + seal the key. "keyctl print" returns an ascii hex copy of the sealed key, which is in standard TPM_STORED_DATA format. The key length for new keys are always in bytes. diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c index d9d0822..45a6340 100644 --- a/drivers/char/tpm/tpm2-cmd.c +++ b/drivers/char/tpm/tpm2-cmd.c @@ -478,12 +478,26 @@ int tpm2_seal_trusted(struct tpm_chip *chip, tpm_buf_append_u8(, payload->migratable); /* public */ - tpm_buf_append_u16(, 14); + if (options->policydigest) + tpm_buf_append_u16(, 14 + options->digest_len); + else + tpm_buf_append_u16(, 14); tpm_buf_append_u16(, TPM2_ALG_KEYEDHASH); tpm_buf_append_u16(, hash); - tpm_buf_append_u32(, TPM2_ATTR_USER_WITH_AUTH); - tpm_buf_append_u16(, 0); /* policy digest size */ + + /* policy */ + if (options->policydigest) { + tpm_buf_append_u32(, 0); + tpm_buf_append_u16(, options->digest_len); + tpm_buf_append(, options->policydigest, + options->digest_len); + } else { + tpm_buf_append_u32(, TPM2_ATTR_USER_WITH_AUTH); + tpm_buf_append_u16(, 0); + } + + /* public parameters */ tpm_buf_append_u16(, TPM2_ALG_NULL); tpm_buf_append_u16(, 0); @@ -613,7 +627,9 @@ static int tpm2_unseal(struct tpm_chip *chip, return rc;
[PATCH v2 1/3] keys, trusted: fix: *do not* allow duplicate key options
The trusted keys option parsing allows specifying the same option multiple times. The last option value specified is used. This can be seen as a regression because: * No gain. * Could be problematic if there is be options dependent on other options. Reported-by: James Morris James MorrisSigned-off-by: Jarkko Sakkinen --- security/keys/trusted.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/security/keys/trusted.c b/security/keys/trusted.c index 903dace..7c183c7 100644 --- a/security/keys/trusted.c +++ b/security/keys/trusted.c @@ -736,11 +736,14 @@ static int getoptions(char *c, struct trusted_key_payload *pay, int res; unsigned long handle; unsigned long lock; + unsigned long token_mask = 0; while ((p = strsep(, " \t"))) { if (*p == '\0' || *p == ' ' || *p == '\t') continue; token = match_token(p, key_tokens, args); + if (test_and_set_bit(token, _mask)) + return -EINVAL; switch (token) { case Opt_pcrinfo: -- 2.5.0 -- To unsubscribe from this list: send the line "unsubscribe linux-security-module" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 2/3] keys, trusted: select hash algorithm for TPM2 chips
Added 'hash=' option for selecting the hash algorithm for add_key() syscall and documentation for it. Added entry for sm3-256 to the following tables in order to support TPM_ALG_SM3_256: * hash_algo_name * hash_digest_size Includes support for the following hash algorithms: * sha1 * sha256 * sha384 * sha512 * sm3-256 Signed-off-by: Jarkko SakkinenTested-by: Colin Ian King Reviewed-by: James Morris --- Documentation/security/keys-trusted-encrypted.txt | 3 ++ crypto/hash_info.c| 2 ++ drivers/char/tpm/tpm.h| 10 +-- drivers/char/tpm/tpm2-cmd.c | 36 +-- include/crypto/hash_info.h| 3 ++ include/keys/trusted-type.h | 1 + include/uapi/linux/hash_info.h| 1 + security/keys/Kconfig | 1 + security/keys/trusted.c | 27 - 9 files changed, 77 insertions(+), 7 deletions(-) diff --git a/Documentation/security/keys-trusted-encrypted.txt b/Documentation/security/keys-trusted-encrypted.txt index e105ae9..fd2565b 100644 --- a/Documentation/security/keys-trusted-encrypted.txt +++ b/Documentation/security/keys-trusted-encrypted.txt @@ -38,6 +38,9 @@ Usage: pcrlock= pcr number to be extended to "lock" blob migratable= 0|1 indicating permission to reseal to new PCR values, default 1 (resealing allowed) + hash= hash algorithm name as a string. For TPM 1.x the only + allowed value is sha1. For TPM 2.x the allowed values + are sha1, sha256, sha384, sha512 and sm3-256. "keyctl print" returns an ascii hex copy of the sealed key, which is in standard TPM_STORED_DATA format. The key length for new keys are always in bytes. diff --git a/crypto/hash_info.c b/crypto/hash_info.c index 3e7ff46..7b1e0b1 100644 --- a/crypto/hash_info.c +++ b/crypto/hash_info.c @@ -31,6 +31,7 @@ const char *const hash_algo_name[HASH_ALGO__LAST] = { [HASH_ALGO_TGR_128] = "tgr128", [HASH_ALGO_TGR_160] = "tgr160", [HASH_ALGO_TGR_192] = "tgr192", + [HASH_ALGO_SM3_256] = "sm3-256", }; EXPORT_SYMBOL_GPL(hash_algo_name); @@ -52,5 +53,6 @@ const int hash_digest_size[HASH_ALGO__LAST] = { [HASH_ALGO_TGR_128] = TGR128_DIGEST_SIZE, [HASH_ALGO_TGR_160] = TGR160_DIGEST_SIZE, [HASH_ALGO_TGR_192] = TGR192_DIGEST_SIZE, + [HASH_ALGO_SM3_256] = SM3256_DIGEST_SIZE, }; EXPORT_SYMBOL_GPL(hash_digest_size); diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index 347fc61..542a80c 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h @@ -83,16 +83,20 @@ enum tpm2_structures { }; enum tpm2_return_codes { - TPM2_RC_INITIALIZE = 0x0100, - TPM2_RC_TESTING = 0x090A, + TPM2_RC_HASH= 0x0083, /* RC_FMT1 */ + TPM2_RC_INITIALIZE = 0x0100, /* RC_VER1 */ TPM2_RC_DISABLED= 0x0120, + TPM2_RC_TESTING = 0x090A, /* RC_WARN */ }; enum tpm2_algorithms { TPM2_ALG_SHA1 = 0x0004, TPM2_ALG_KEYEDHASH = 0x0008, TPM2_ALG_SHA256 = 0x000B, - TPM2_ALG_NULL = 0x0010 + TPM2_ALG_SHA384 = 0x000C, + TPM2_ALG_SHA512 = 0x000D, + TPM2_ALG_NULL = 0x0010, + TPM2_ALG_SM3_256= 0x0012, }; enum tpm2_command_codes { diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c index c121304..d9d0822 100644 --- a/drivers/char/tpm/tpm2-cmd.c +++ b/drivers/char/tpm/tpm2-cmd.c @@ -16,6 +16,7 @@ */ #include "tpm.h" +#include #include enum tpm2_object_attributes { @@ -104,6 +105,19 @@ struct tpm2_cmd { union tpm2_cmd_params params; } __packed; +struct tpm2_hash { + unsigned int crypto_id; + unsigned int tpm_id; +}; + +static struct tpm2_hash tpm2_hash_map[] = { + {HASH_ALGO_SHA1, TPM2_ALG_SHA1}, + {HASH_ALGO_SHA256, TPM2_ALG_SHA256}, + {HASH_ALGO_SHA384, TPM2_ALG_SHA384}, + {HASH_ALGO_SHA512, TPM2_ALG_SHA512}, + {HASH_ALGO_SM3_256, TPM2_ALG_SM3_256}, +}; + /* * Array with one entry per ordinal defining the maximum amount * of time the chip could take to return the result. The values @@ -429,8 +443,20 @@ int tpm2_seal_trusted(struct tpm_chip *chip, { unsigned int blob_len; struct tpm_buf buf; + u32 hash; + int i; int rc; + for (i = 0; i < ARRAY_SIZE(tpm2_hash_map); i++) { + if (options->hash == tpm2_hash_map[i].crypto_id) { + hash = tpm2_hash_map[i].tpm_id; + break; + } + } + + if (i == ARRAY_SIZE(tpm2_hash_map)) + return -EINVAL; + rc =
Re: Exposing secid to secctx mapping to user-space
On Friday, December 11, 2015 05:14:38 PM Stephen Smalley wrote: > Perhaps we could provide a new fixed-size tokenized version of the > security context string for export to userspace that could be embedded > in the binder transaction structure? This could avoid both the > limitations of the current secid (e.g. limited to 32 bits, no > stackability) and the overhead of copying context strings on every IPC. On Friday, December 11, 2015 04:24:48 PM Casey Schaufler wrote: > How about this: Provide an alias mechanism for secctx. There would then > be a secid (32bits) a secctx (arbitrary text string) and a secalias which > could be a limited string of some length. You could use the alias in place > of the secctx anywhere you liked. My initial reaction to the secalias idea isn't overly positive. It seems like a kludge with a lot of duplication, both in terms of code and concept, and a lot of risk for confusion both by users and policy writers. I think if we really wanted to limit the security label string format to a small size we should have done that from the start, it's too late now. Assuming we see some binder performance numbers, and the numbers are bad, I'm a little more open to doing something with the secid token. Up to this point we haven't made any guarantees about the token and we haven't exported it outside the kernel so there is some ability to change it to fit our needs. Granted, this isn't perfect solution either, and perhaps ultimately we would need something else, but I think it is worth looking into this first before we introduce another string label. -- paul moore www.paul-moore.com -- To unsubscribe from this list: send the line "unsubscribe linux-security-module" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
SELinux/audit kernel repo process changes
In an effort to make it a bit easier to maintain the kernel-secnext COPR I'm making some slight changes to how I manage the SELinux and audit kernel repositories. The downside is that there is now going to be a regular rebase as part of the release cycle, but at least it will be well defined and part of the process, unlike the current reactionary rebases. Starting with the next merge window, I'll be following the process below: 1. When a new kernel is released, rebase the repository's upstream branch to the tagged kernel release (or the latest LSM upstream branch in the case of SELinux) and apply the next branch on top of the upstream branch. Send a pull request for the upstream branch to the next level maintainer. 2. Create a new branch, stable-X.XX, a copy of the upstream branch that was sent during the merge window. 3. Reset the next branch to the upstream branch that was sent during the merge window. At this point the upstream, next, and latest stable-X.XX branch should be identical. 4. Accept patches into both the stable-X.XX and next branches; as necessary, send pull requests for stable-X.XX to the next level maintainer. Continue until the next kernel is released and the process repeats. As in the past, this process is subject to change, but I'm hopeful that this approach should work for the foreseeable future. -- paul moore www.paul-moore.com -- To unsubscribe from this list: send the line "unsubscribe linux-security-module" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html