diff options
author | Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> | 2015-11-05 14:43:06 -0500 |
---|---|---|
committer | Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> | 2015-12-20 08:27:12 -0500 |
commit | 5ca4c20cfd37bac6486de040e9951b3b34755238 (patch) | |
tree | 1ee427b120ae979e1cd30b7bc47c31426066deae | |
parent | 5208cc83423dde06924121a85368c721a27ca555 (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.txt | 3 | ||||
-rw-r--r-- | crypto/hash_info.c | 2 | ||||
-rw-r--r-- | drivers/char/tpm/tpm.h | 10 | ||||
-rw-r--r-- | drivers/char/tpm/tpm2-cmd.c | 36 | ||||
-rw-r--r-- | include/crypto/hash_info.h | 3 | ||||
-rw-r--r-- | include/keys/trusted-type.h | 1 | ||||
-rw-r--r-- | include/uapi/linux/hash_info.h | 1 | ||||
-rw-r--r-- | security/keys/Kconfig | 1 | ||||
-rw-r--r-- | 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 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 |
43 | TPM_STORED_DATA format. The key length for new keys are always in bytes. | 46 | 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 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 | }; |
35 | EXPORT_SYMBOL_GPL(hash_algo_name); | 36 | EXPORT_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 | }; |
56 | EXPORT_SYMBOL_GPL(hash_digest_size); | 58 | EXPORT_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 | ||
85 | enum tpm2_return_codes { | 85 | enum 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 | ||
91 | enum tpm2_algorithms { | 92 | enum 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 | ||
98 | enum tpm2_command_codes { | 102 | enum 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 | ||
21 | enum tpm2_object_attributes { | 22 | enum 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 | ||
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 | |||
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, | |||
488 | out: | 514 | out: |
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 | |||
37 | extern const char *const hash_algo_name[HASH_ALGO__LAST]; | 40 | extern const char *const hash_algo_name[HASH_ALGO__LAST]; |
38 | extern const int hash_digest_size[HASH_ALGO__LAST]; | 41 | extern 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 | ||
41 | extern struct key_type key_type_trusted; | 42 | extern 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 | ||
716 | static const match_table_t key_tokens = { | 718 | static 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 | } |