Skip to content

Commit 5ca4c20

Browse files
author
Jarkko Sakkinen
committed
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>
1 parent 5208cc8 commit 5ca4c20

File tree

9 files changed

+77
-7
lines changed

9 files changed

+77
-7
lines changed

Documentation/security/keys-trusted-encrypted.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ Usage:
3838
pcrlock= pcr number to be extended to "lock" blob
3939
migratable= 0|1 indicating permission to reseal to new PCR values,
4040
default 1 (resealing allowed)
41+
hash= hash algorithm name as a string. For TPM 1.x the only
42+
allowed value is sha1. For TPM 2.x the allowed values
43+
are sha1, sha256, sha384, sha512 and sm3-256.
4144

4245
"keyctl print" returns an ascii hex copy of the sealed key, which is in standard
4346
TPM_STORED_DATA format. The key length for new keys are always in bytes.

crypto/hash_info.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ const char *const hash_algo_name[HASH_ALGO__LAST] = {
3131
[HASH_ALGO_TGR_128] = "tgr128",
3232
[HASH_ALGO_TGR_160] = "tgr160",
3333
[HASH_ALGO_TGR_192] = "tgr192",
34+
[HASH_ALGO_SM3_256] = "sm3-256",
3435
};
3536
EXPORT_SYMBOL_GPL(hash_algo_name);
3637

@@ -52,5 +53,6 @@ const int hash_digest_size[HASH_ALGO__LAST] = {
5253
[HASH_ALGO_TGR_128] = TGR128_DIGEST_SIZE,
5354
[HASH_ALGO_TGR_160] = TGR160_DIGEST_SIZE,
5455
[HASH_ALGO_TGR_192] = TGR192_DIGEST_SIZE,
56+
[HASH_ALGO_SM3_256] = SM3256_DIGEST_SIZE,
5557
};
5658
EXPORT_SYMBOL_GPL(hash_digest_size);

drivers/char/tpm/tpm.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,16 +83,20 @@ enum tpm2_structures {
8383
};
8484

8585
enum tpm2_return_codes {
86-
TPM2_RC_INITIALIZE = 0x0100,
87-
TPM2_RC_TESTING = 0x090A,
86+
TPM2_RC_HASH = 0x0083, /* RC_FMT1 */
87+
TPM2_RC_INITIALIZE = 0x0100, /* RC_VER1 */
8888
TPM2_RC_DISABLED = 0x0120,
89+
TPM2_RC_TESTING = 0x090A, /* RC_WARN */
8990
};
9091

9192
enum tpm2_algorithms {
9293
TPM2_ALG_SHA1 = 0x0004,
9394
TPM2_ALG_KEYEDHASH = 0x0008,
9495
TPM2_ALG_SHA256 = 0x000B,
95-
TPM2_ALG_NULL = 0x0010
96+
TPM2_ALG_SHA384 = 0x000C,
97+
TPM2_ALG_SHA512 = 0x000D,
98+
TPM2_ALG_NULL = 0x0010,
99+
TPM2_ALG_SM3_256 = 0x0012,
96100
};
97101

98102
enum tpm2_command_codes {

drivers/char/tpm/tpm2-cmd.c

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
*/
1717

1818
#include "tpm.h"
19+
#include <crypto/hash_info.h>
1920
#include <keys/trusted-type.h>
2021

2122
enum tpm2_object_attributes {
@@ -104,6 +105,19 @@ struct tpm2_cmd {
104105
union tpm2_cmd_params params;
105106
} __packed;
106107

108+
struct tpm2_hash {
109+
unsigned int crypto_id;
110+
unsigned int tpm_id;
111+
};
112+
113+
static struct tpm2_hash tpm2_hash_map[] = {
114+
{HASH_ALGO_SHA1, TPM2_ALG_SHA1},
115+
{HASH_ALGO_SHA256, TPM2_ALG_SHA256},
116+
{HASH_ALGO_SHA384, TPM2_ALG_SHA384},
117+
{HASH_ALGO_SHA512, TPM2_ALG_SHA512},
118+
{HASH_ALGO_SM3_256, TPM2_ALG_SM3_256},
119+
};
120+
107121
/*
108122
* Array with one entry per ordinal defining the maximum amount
109123
* of time the chip could take to return the result. The values
@@ -429,8 +443,20 @@ int tpm2_seal_trusted(struct tpm_chip *chip,
429443
{
430444
unsigned int blob_len;
431445
struct tpm_buf buf;
446+
u32 hash;
447+
int i;
432448
int rc;
433449

450+
for (i = 0; i < ARRAY_SIZE(tpm2_hash_map); i++) {
451+
if (options->hash == tpm2_hash_map[i].crypto_id) {
452+
hash = tpm2_hash_map[i].tpm_id;
453+
break;
454+
}
455+
}
456+
457+
if (i == ARRAY_SIZE(tpm2_hash_map))
458+
return -EINVAL;
459+
434460
rc = tpm_buf_init(&buf, TPM2_ST_SESSIONS, TPM2_CC_CREATE);
435461
if (rc)
436462
return rc;
@@ -455,7 +481,7 @@ int tpm2_seal_trusted(struct tpm_chip *chip,
455481
tpm_buf_append_u16(&buf, 14);
456482

457483
tpm_buf_append_u16(&buf, TPM2_ALG_KEYEDHASH);
458-
tpm_buf_append_u16(&buf, TPM2_ALG_SHA256);
484+
tpm_buf_append_u16(&buf, hash);
459485
tpm_buf_append_u32(&buf, TPM2_ATTR_USER_WITH_AUTH);
460486
tpm_buf_append_u16(&buf, 0); /* policy digest size */
461487
tpm_buf_append_u16(&buf, TPM2_ALG_NULL);
@@ -488,8 +514,12 @@ int tpm2_seal_trusted(struct tpm_chip *chip,
488514
out:
489515
tpm_buf_destroy(&buf);
490516

491-
if (rc > 0)
492-
rc = -EPERM;
517+
if (rc > 0) {
518+
if ((rc & TPM2_RC_HASH) == TPM2_RC_HASH)
519+
rc = -EINVAL;
520+
else
521+
rc = -EPERM;
522+
}
493523

494524
return rc;
495525
}

include/crypto/hash_info.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@
3434
#define TGR160_DIGEST_SIZE 20
3535
#define TGR192_DIGEST_SIZE 24
3636

37+
/* not defined in include/crypto/ */
38+
#define SM3256_DIGEST_SIZE 32
39+
3740
extern const char *const hash_algo_name[HASH_ALGO__LAST];
3841
extern const int hash_digest_size[HASH_ALGO__LAST];
3942

include/keys/trusted-type.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ struct trusted_key_options {
3636
uint32_t pcrinfo_len;
3737
unsigned char pcrinfo[MAX_PCRINFO_SIZE];
3838
int pcrlock;
39+
uint32_t hash;
3940
};
4041

4142
extern struct key_type key_type_trusted;

include/uapi/linux/hash_info.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ enum hash_algo {
3131
HASH_ALGO_TGR_128,
3232
HASH_ALGO_TGR_160,
3333
HASH_ALGO_TGR_192,
34+
HASH_ALGO_SM3_256,
3435
HASH_ALGO__LAST
3536
};
3637

security/keys/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ config TRUSTED_KEYS
5454
select CRYPTO
5555
select CRYPTO_HMAC
5656
select CRYPTO_SHA1
57+
select CRYPTO_HASH_INFO
5758
help
5859
This option provides support for creating, sealing, and unsealing
5960
keys in the kernel. Trusted keys are random number symmetric keys,

security/keys/trusted.c

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
* See Documentation/security/keys-trusted-encrypted.txt
1212
*/
1313

14+
#include <crypto/hash_info.h>
1415
#include <linux/uaccess.h>
1516
#include <linux/module.h>
1617
#include <linux/init.h>
@@ -710,7 +711,8 @@ enum {
710711
Opt_err = -1,
711712
Opt_new, Opt_load, Opt_update,
712713
Opt_keyhandle, Opt_keyauth, Opt_blobauth,
713-
Opt_pcrinfo, Opt_pcrlock, Opt_migratable
714+
Opt_pcrinfo, Opt_pcrlock, Opt_migratable,
715+
Opt_hash,
714716
};
715717

716718
static const match_table_t key_tokens = {
@@ -723,6 +725,7 @@ static const match_table_t key_tokens = {
723725
{Opt_pcrinfo, "pcrinfo=%s"},
724726
{Opt_pcrlock, "pcrlock=%s"},
725727
{Opt_migratable, "migratable=%s"},
728+
{Opt_hash, "hash=%s"},
726729
{Opt_err, NULL}
727730
};
728731

@@ -737,6 +740,14 @@ static int getoptions(char *c, struct trusted_key_payload *pay,
737740
unsigned long handle;
738741
unsigned long lock;
739742
unsigned long token_mask = 0;
743+
int i;
744+
int tpm2;
745+
746+
tpm2 = tpm_is_tpm2(TPM_ANY_NUM);
747+
if (tpm2 < 0)
748+
return tpm2;
749+
750+
opt->hash = tpm2 ? HASH_ALGO_SHA256 : HASH_ALGO_SHA1;
740751

741752
while ((p = strsep(&c, " \t"))) {
742753
if (*p == '\0' || *p == ' ' || *p == '\t')
@@ -790,6 +801,20 @@ static int getoptions(char *c, struct trusted_key_payload *pay,
790801
return -EINVAL;
791802
opt->pcrlock = lock;
792803
break;
804+
case Opt_hash:
805+
for (i = 0; i < HASH_ALGO__LAST; i++) {
806+
if (!strcmp(args[0].from, hash_algo_name[i])) {
807+
opt->hash = i;
808+
break;
809+
}
810+
}
811+
if (i == HASH_ALGO__LAST)
812+
return -EINVAL;
813+
if (!tpm2 && i != HASH_ALGO_SHA1) {
814+
pr_info("trusted_key: TPM 1.x only supports SHA-1.\n");
815+
return -EINVAL;
816+
}
817+
break;
793818
default:
794819
return -EINVAL;
795820
}

0 commit comments

Comments
 (0)