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 Sakkinen <jarkko.sakkinen@linux.intel.com> Tested-by: Colin Ian King <colin.king@canonical.com> Reviewed-by: James Morris <james.l.morris@oracle.com> Reviewed-by: Mimi Zohar <zohar@linux.vnet.ibm.com> Acked-by: Peter Huewe <peterhuewe@gmx.de>
This commit is contained in:
parent
5208cc8342
commit
5ca4c20cfd
9 changed files with 77 additions and 7 deletions
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
*/
|
||||
|
||||
#include "tpm.h"
|
||||
#include <crypto/hash_info.h>
|
||||
#include <keys/trusted-type.h>
|
||||
|
||||
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 = tpm_buf_init(&buf, TPM2_ST_SESSIONS, TPM2_CC_CREATE);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
@ -455,7 +481,7 @@ int tpm2_seal_trusted(struct tpm_chip *chip,
|
|||
tpm_buf_append_u16(&buf, 14);
|
||||
|
||||
tpm_buf_append_u16(&buf, TPM2_ALG_KEYEDHASH);
|
||||
tpm_buf_append_u16(&buf, TPM2_ALG_SHA256);
|
||||
tpm_buf_append_u16(&buf, hash);
|
||||
tpm_buf_append_u32(&buf, TPM2_ATTR_USER_WITH_AUTH);
|
||||
tpm_buf_append_u16(&buf, 0); /* policy digest size */
|
||||
tpm_buf_append_u16(&buf, TPM2_ALG_NULL);
|
||||
|
@ -488,8 +514,12 @@ int tpm2_seal_trusted(struct tpm_chip *chip,
|
|||
out:
|
||||
tpm_buf_destroy(&buf);
|
||||
|
||||
if (rc > 0)
|
||||
rc = -EPERM;
|
||||
if (rc > 0) {
|
||||
if ((rc & TPM2_RC_HASH) == TPM2_RC_HASH)
|
||||
rc = -EINVAL;
|
||||
else
|
||||
rc = -EPERM;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -34,6 +34,9 @@
|
|||
#define TGR160_DIGEST_SIZE 20
|
||||
#define TGR192_DIGEST_SIZE 24
|
||||
|
||||
/* not defined in include/crypto/ */
|
||||
#define SM3256_DIGEST_SIZE 32
|
||||
|
||||
extern const char *const hash_algo_name[HASH_ALGO__LAST];
|
||||
extern const int hash_digest_size[HASH_ALGO__LAST];
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@ struct trusted_key_options {
|
|||
uint32_t pcrinfo_len;
|
||||
unsigned char pcrinfo[MAX_PCRINFO_SIZE];
|
||||
int pcrlock;
|
||||
uint32_t hash;
|
||||
};
|
||||
|
||||
extern struct key_type key_type_trusted;
|
||||
|
|
|
@ -31,6 +31,7 @@ enum hash_algo {
|
|||
HASH_ALGO_TGR_128,
|
||||
HASH_ALGO_TGR_160,
|
||||
HASH_ALGO_TGR_192,
|
||||
HASH_ALGO_SM3_256,
|
||||
HASH_ALGO__LAST
|
||||
};
|
||||
|
||||
|
|
|
@ -54,6 +54,7 @@ config TRUSTED_KEYS
|
|||
select CRYPTO
|
||||
select CRYPTO_HMAC
|
||||
select CRYPTO_SHA1
|
||||
select CRYPTO_HASH_INFO
|
||||
help
|
||||
This option provides support for creating, sealing, and unsealing
|
||||
keys in the kernel. Trusted keys are random number symmetric keys,
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
* See Documentation/security/keys-trusted-encrypted.txt
|
||||
*/
|
||||
|
||||
#include <crypto/hash_info.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
|
@ -710,7 +711,8 @@ enum {
|
|||
Opt_err = -1,
|
||||
Opt_new, Opt_load, Opt_update,
|
||||
Opt_keyhandle, Opt_keyauth, Opt_blobauth,
|
||||
Opt_pcrinfo, Opt_pcrlock, Opt_migratable
|
||||
Opt_pcrinfo, Opt_pcrlock, Opt_migratable,
|
||||
Opt_hash,
|
||||
};
|
||||
|
||||
static const match_table_t key_tokens = {
|
||||
|
@ -723,6 +725,7 @@ static const match_table_t key_tokens = {
|
|||
{Opt_pcrinfo, "pcrinfo=%s"},
|
||||
{Opt_pcrlock, "pcrlock=%s"},
|
||||
{Opt_migratable, "migratable=%s"},
|
||||
{Opt_hash, "hash=%s"},
|
||||
{Opt_err, NULL}
|
||||
};
|
||||
|
||||
|
@ -737,6 +740,14 @@ static int getoptions(char *c, struct trusted_key_payload *pay,
|
|||
unsigned long handle;
|
||||
unsigned long lock;
|
||||
unsigned long token_mask = 0;
|
||||
int i;
|
||||
int tpm2;
|
||||
|
||||
tpm2 = tpm_is_tpm2(TPM_ANY_NUM);
|
||||
if (tpm2 < 0)
|
||||
return tpm2;
|
||||
|
||||
opt->hash = tpm2 ? HASH_ALGO_SHA256 : HASH_ALGO_SHA1;
|
||||
|
||||
while ((p = strsep(&c, " \t"))) {
|
||||
if (*p == '\0' || *p == ' ' || *p == '\t')
|
||||
|
@ -790,6 +801,20 @@ static int getoptions(char *c, struct trusted_key_payload *pay,
|
|||
return -EINVAL;
|
||||
opt->pcrlock = lock;
|
||||
break;
|
||||
case Opt_hash:
|
||||
for (i = 0; i < HASH_ALGO__LAST; i++) {
|
||||
if (!strcmp(args[0].from, hash_algo_name[i])) {
|
||||
opt->hash = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == HASH_ALGO__LAST)
|
||||
return -EINVAL;
|
||||
if (!tpm2 && i != HASH_ALGO_SHA1) {
|
||||
pr_info("trusted_key: TPM 1.x only supports SHA-1.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue