summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJarkko Sakkinen <jarkko.sakkinen@linux.intel.com>2015-11-05 14:43:06 -0500
committerJarkko Sakkinen <jarkko.sakkinen@linux.intel.com>2015-12-20 08:27:12 -0500
commit5ca4c20cfd37bac6486de040e9951b3b34755238 (patch)
tree1ee427b120ae979e1cd30b7bc47c31426066deae
parent5208cc83423dde06924121a85368c721a27ca555 (diff)
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>
-rw-r--r--Documentation/security/keys-trusted-encrypted.txt3
-rw-r--r--crypto/hash_info.c2
-rw-r--r--drivers/char/tpm/tpm.h10
-rw-r--r--drivers/char/tpm/tpm2-cmd.c36
-rw-r--r--include/crypto/hash_info.h3
-rw-r--r--include/keys/trusted-type.h1
-rw-r--r--include/uapi/linux/hash_info.h1
-rw-r--r--security/keys/Kconfig1
-rw-r--r--security/keys/trusted.c27
9 files changed, 77 insertions, 7 deletions
diff --git a/Documentation/security/keys-trusted-encrypted.txt b/Documentation/security/keys-trusted-encrypted.txt
index e105ae97a4f5..fd2565b301e8 100644
--- a/Documentation/security/keys-trusted-encrypted.txt
+++ b/Documentation/security/keys-trusted-encrypted.txt
@@ -38,6 +38,9 @@ Usage:
38 pcrlock= pcr number to be extended to "lock" blob 38 pcrlock= pcr number to be extended to "lock" blob
39 migratable= 0|1 indicating permission to reseal to new PCR values, 39 migratable= 0|1 indicating permission to reseal to new PCR values,
40 default 1 (resealing allowed) 40 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.
41 44
42"keyctl print" returns an ascii hex copy of the sealed key, which is in standard 45"keyctl print" returns an ascii hex copy of the sealed key, which is in standard
43TPM_STORED_DATA format. The key length for new keys are always in bytes. 46TPM_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 3e7ff46f26e8..7b1e0b188ce6 100644
--- a/crypto/hash_info.c
+++ b/crypto/hash_info.c
@@ -31,6 +31,7 @@ const char *const hash_algo_name[HASH_ALGO__LAST] = {
31 [HASH_ALGO_TGR_128] = "tgr128", 31 [HASH_ALGO_TGR_128] = "tgr128",
32 [HASH_ALGO_TGR_160] = "tgr160", 32 [HASH_ALGO_TGR_160] = "tgr160",
33 [HASH_ALGO_TGR_192] = "tgr192", 33 [HASH_ALGO_TGR_192] = "tgr192",
34 [HASH_ALGO_SM3_256] = "sm3-256",
34}; 35};
35EXPORT_SYMBOL_GPL(hash_algo_name); 36EXPORT_SYMBOL_GPL(hash_algo_name);
36 37
@@ -52,5 +53,6 @@ const int hash_digest_size[HASH_ALGO__LAST] = {
52 [HASH_ALGO_TGR_128] = TGR128_DIGEST_SIZE, 53 [HASH_ALGO_TGR_128] = TGR128_DIGEST_SIZE,
53 [HASH_ALGO_TGR_160] = TGR160_DIGEST_SIZE, 54 [HASH_ALGO_TGR_160] = TGR160_DIGEST_SIZE,
54 [HASH_ALGO_TGR_192] = TGR192_DIGEST_SIZE, 55 [HASH_ALGO_TGR_192] = TGR192_DIGEST_SIZE,
56 [HASH_ALGO_SM3_256] = SM3256_DIGEST_SIZE,
55}; 57};
56EXPORT_SYMBOL_GPL(hash_digest_size); 58EXPORT_SYMBOL_GPL(hash_digest_size);
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 347fc615bcc9..542a80cbfd9c 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -83,16 +83,20 @@ enum tpm2_structures {
83}; 83};
84 84
85enum tpm2_return_codes { 85enum tpm2_return_codes {
86 TPM2_RC_INITIALIZE = 0x0100, 86 TPM2_RC_HASH = 0x0083, /* RC_FMT1 */
87 TPM2_RC_TESTING = 0x090A, 87 TPM2_RC_INITIALIZE = 0x0100, /* RC_VER1 */
88 TPM2_RC_DISABLED = 0x0120, 88 TPM2_RC_DISABLED = 0x0120,
89 TPM2_RC_TESTING = 0x090A, /* RC_WARN */
89}; 90};
90 91
91enum tpm2_algorithms { 92enum tpm2_algorithms {
92 TPM2_ALG_SHA1 = 0x0004, 93 TPM2_ALG_SHA1 = 0x0004,
93 TPM2_ALG_KEYEDHASH = 0x0008, 94 TPM2_ALG_KEYEDHASH = 0x0008,
94 TPM2_ALG_SHA256 = 0x000B, 95 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,
96}; 100};
97 101
98enum tpm2_command_codes { 102enum tpm2_command_codes {
diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c
index c12130485fc1..d9d082206f6e 100644
--- a/drivers/char/tpm/tpm2-cmd.c
+++ b/drivers/char/tpm/tpm2-cmd.c
@@ -16,6 +16,7 @@
16 */ 16 */
17 17
18#include "tpm.h" 18#include "tpm.h"
19#include <crypto/hash_info.h>
19#include <keys/trusted-type.h> 20#include <keys/trusted-type.h>
20 21
21enum tpm2_object_attributes { 22enum tpm2_object_attributes {
@@ -104,6 +105,19 @@ struct tpm2_cmd {
104 union tpm2_cmd_params params; 105 union tpm2_cmd_params params;
105} __packed; 106} __packed;
106 107
108struct tpm2_hash {
109 unsigned int crypto_id;
110 unsigned int tpm_id;
111};
112
113static 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
107/* 121/*
108 * Array with one entry per ordinal defining the maximum amount 122 * Array with one entry per ordinal defining the maximum amount
109 * of time the chip could take to return the result. The values 123 * of time the chip could take to return the result. The values
@@ -429,8 +443,20 @@ int tpm2_seal_trusted(struct tpm_chip *chip,
429{ 443{
430 unsigned int blob_len; 444 unsigned int blob_len;
431 struct tpm_buf buf; 445 struct tpm_buf buf;
446 u32 hash;
447 int i;
432 int rc; 448 int rc;
433 449
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
434 rc = tpm_buf_init(&buf, TPM2_ST_SESSIONS, TPM2_CC_CREATE); 460 rc = tpm_buf_init(&buf, TPM2_ST_SESSIONS, TPM2_CC_CREATE);
435 if (rc) 461 if (rc)
436 return rc; 462 return rc;
@@ -455,7 +481,7 @@ int tpm2_seal_trusted(struct tpm_chip *chip,
455 tpm_buf_append_u16(&buf, 14); 481 tpm_buf_append_u16(&buf, 14);
456 482
457 tpm_buf_append_u16(&buf, TPM2_ALG_KEYEDHASH); 483 tpm_buf_append_u16(&buf, TPM2_ALG_KEYEDHASH);
458 tpm_buf_append_u16(&buf, TPM2_ALG_SHA256); 484 tpm_buf_append_u16(&buf, hash);
459 tpm_buf_append_u32(&buf, TPM2_ATTR_USER_WITH_AUTH); 485 tpm_buf_append_u32(&buf, TPM2_ATTR_USER_WITH_AUTH);
460 tpm_buf_append_u16(&buf, 0); /* policy digest size */ 486 tpm_buf_append_u16(&buf, 0); /* policy digest size */
461 tpm_buf_append_u16(&buf, TPM2_ALG_NULL); 487 tpm_buf_append_u16(&buf, TPM2_ALG_NULL);
@@ -488,8 +514,12 @@ int tpm2_seal_trusted(struct tpm_chip *chip,
488out: 514out:
489 tpm_buf_destroy(&buf); 515 tpm_buf_destroy(&buf);
490 516
491 if (rc > 0) 517 if (rc > 0) {
492 rc = -EPERM; 518 if ((rc & TPM2_RC_HASH) == TPM2_RC_HASH)
519 rc = -EINVAL;
520 else
521 rc = -EPERM;
522 }
493 523
494 return rc; 524 return rc;
495} 525}
diff --git a/include/crypto/hash_info.h b/include/crypto/hash_info.h
index e1e5a3e5dd1b..56f217d41f12 100644
--- a/include/crypto/hash_info.h
+++ b/include/crypto/hash_info.h
@@ -34,6 +34,9 @@
34#define TGR160_DIGEST_SIZE 20 34#define TGR160_DIGEST_SIZE 20
35#define TGR192_DIGEST_SIZE 24 35#define TGR192_DIGEST_SIZE 24
36 36
37/* not defined in include/crypto/ */
38#define SM3256_DIGEST_SIZE 32
39
37extern const char *const hash_algo_name[HASH_ALGO__LAST]; 40extern const char *const hash_algo_name[HASH_ALGO__LAST];
38extern const int hash_digest_size[HASH_ALGO__LAST]; 41extern const int hash_digest_size[HASH_ALGO__LAST];
39 42
diff --git a/include/keys/trusted-type.h b/include/keys/trusted-type.h
index f91ecd9d1bb1..a6a100833ae9 100644
--- a/include/keys/trusted-type.h
+++ b/include/keys/trusted-type.h
@@ -36,6 +36,7 @@ struct trusted_key_options {
36 uint32_t pcrinfo_len; 36 uint32_t pcrinfo_len;
37 unsigned char pcrinfo[MAX_PCRINFO_SIZE]; 37 unsigned char pcrinfo[MAX_PCRINFO_SIZE];
38 int pcrlock; 38 int pcrlock;
39 uint32_t hash;
39}; 40};
40 41
41extern struct key_type key_type_trusted; 42extern struct key_type key_type_trusted;
diff --git a/include/uapi/linux/hash_info.h b/include/uapi/linux/hash_info.h
index ca18c45f8304..ebf8fd885dd5 100644
--- a/include/uapi/linux/hash_info.h
+++ b/include/uapi/linux/hash_info.h
@@ -31,6 +31,7 @@ enum hash_algo {
31 HASH_ALGO_TGR_128, 31 HASH_ALGO_TGR_128,
32 HASH_ALGO_TGR_160, 32 HASH_ALGO_TGR_160,
33 HASH_ALGO_TGR_192, 33 HASH_ALGO_TGR_192,
34 HASH_ALGO_SM3_256,
34 HASH_ALGO__LAST 35 HASH_ALGO__LAST
35}; 36};
36 37
diff --git a/security/keys/Kconfig b/security/keys/Kconfig
index 72483b8f1be5..fe4d74e126a7 100644
--- a/security/keys/Kconfig
+++ b/security/keys/Kconfig
@@ -54,6 +54,7 @@ config TRUSTED_KEYS
54 select CRYPTO 54 select CRYPTO
55 select CRYPTO_HMAC 55 select CRYPTO_HMAC
56 select CRYPTO_SHA1 56 select CRYPTO_SHA1
57 select CRYPTO_HASH_INFO
57 help 58 help
58 This option provides support for creating, sealing, and unsealing 59 This option provides support for creating, sealing, and unsealing
59 keys in the kernel. Trusted keys are random number symmetric keys, 60 keys in the kernel. Trusted keys are random number symmetric keys,
diff --git a/security/keys/trusted.c b/security/keys/trusted.c
index 7c183c767a3a..8f1300cab38e 100644
--- a/security/keys/trusted.c
+++ b/security/keys/trusted.c
@@ -11,6 +11,7 @@
11 * See Documentation/security/keys-trusted-encrypted.txt 11 * See Documentation/security/keys-trusted-encrypted.txt
12 */ 12 */
13 13
14#include <crypto/hash_info.h>
14#include <linux/uaccess.h> 15#include <linux/uaccess.h>
15#include <linux/module.h> 16#include <linux/module.h>
16#include <linux/init.h> 17#include <linux/init.h>
@@ -710,7 +711,8 @@ enum {
710 Opt_err = -1, 711 Opt_err = -1,
711 Opt_new, Opt_load, Opt_update, 712 Opt_new, Opt_load, Opt_update,
712 Opt_keyhandle, Opt_keyauth, Opt_blobauth, 713 Opt_keyhandle, Opt_keyauth, Opt_blobauth,
713 Opt_pcrinfo, Opt_pcrlock, Opt_migratable 714 Opt_pcrinfo, Opt_pcrlock, Opt_migratable,
715 Opt_hash,
714}; 716};
715 717
716static const match_table_t key_tokens = { 718static const match_table_t key_tokens = {
@@ -723,6 +725,7 @@ static const match_table_t key_tokens = {
723 {Opt_pcrinfo, "pcrinfo=%s"}, 725 {Opt_pcrinfo, "pcrinfo=%s"},
724 {Opt_pcrlock, "pcrlock=%s"}, 726 {Opt_pcrlock, "pcrlock=%s"},
725 {Opt_migratable, "migratable=%s"}, 727 {Opt_migratable, "migratable=%s"},
728 {Opt_hash, "hash=%s"},
726 {Opt_err, NULL} 729 {Opt_err, NULL}
727}; 730};
728 731
@@ -737,6 +740,14 @@ static int getoptions(char *c, struct trusted_key_payload *pay,
737 unsigned long handle; 740 unsigned long handle;
738 unsigned long lock; 741 unsigned long lock;
739 unsigned long token_mask = 0; 742 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;
740 751
741 while ((p = strsep(&c, " \t"))) { 752 while ((p = strsep(&c, " \t"))) {
742 if (*p == '\0' || *p == ' ' || *p == '\t') 753 if (*p == '\0' || *p == ' ' || *p == '\t')
@@ -790,6 +801,20 @@ static int getoptions(char *c, struct trusted_key_payload *pay,
790 return -EINVAL; 801 return -EINVAL;
791 opt->pcrlock = lock; 802 opt->pcrlock = lock;
792 break; 803 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;
793 default: 818 default:
794 return -EINVAL; 819 return -EINVAL;
795 } 820 }