KEYS: asymmetric: tpm2_key_rsa
Subsystems (7)
Jarkko Sakkinen
maintainerv4 cover KEYS: asymmetric: tpm2_key_rsa
## Overview
Introduce tpm2_key_rsa module, which implements asymmetric TPM2 RSA key. The feature can be enabled with the CONFIG_ASYMMETRIC_TPM2_KEY_RSA_SUBTYPE kconfig option. This feature allows the private key to be uploaded to the TPM2 for signing, and software can use the public key to verify the signatures.
The idea in the design is to over time to have submodule per key type For instance, tpm2_key_ecdsa could be one potential future addition in the future. Perhaps, it might sense to consider at that point also a top-level tpm2_key module. The gist is that the naming convention is free from potential future bottlencks.
### Testing
tpm2_createprimary --hierarchy o -G rsa2048 -c owner.txt tpm2_evictcontrol -c owner.txt 0x81000001tpm2_getcap handles-persistent
openssl genrsa -out private.pem 2048tpm2_import -C 0x81000001 -G rsa -i private.pem -u key.pub -r key.priv tpm2_encodeobject -C 0x81000001 -u key.pub -r key.priv -o key.priv.pem openssl asn1parse -inform pem -in key.priv.pem -noout -out key.priv.der serial=cat key.priv.der | keyctl padd asymmetric tpm @u
echo "abcdefg" > plaintext.txt
keyctl pkey_encrypt $serial 0 plaintext.txt enc=pkcs1 > encrypted.dat keyctl pkey_decrypt $serial 0 encrypted.dat enc=pkcs1 > decrypted.dat keyctl pkey_sign $serial 0 plaintext.txt enc=pkcs1 hash=sha256 > signed.dat keyctl pkey_verify $serial 0 plaintext.txt signed.dat enc=pkcs1 hash=sha256
## References
- v1: https://lore.kernel.org/linux-integrity/[email protected]/
- Derived from https://lore.kernel.org/all/[email protected]/
James Prestwood (1):
keys: asymmetric: ASYMMETRIC_TPM2_KEY_RSA_SUBTYPE
Jarkko Sakkinen (4):
crypto: rsa-pkcs1pad: export rsa1_asn_lookup()
KEYS: trusted: Change -EINVAL to -E2BIG
KEYS: trusted: Move tpm2_key_decode() to the TPM driver
tpm: tpm2_key: Extend parser to TPM_LoadableKey
crypto/asymmetric_keys/Kconfig | 15 +
crypto/asymmetric_keys/Makefile | 1 +
crypto/asymmetric_keys/tpm2_key_rsa.c | 670 ++++++++++++++++++
crypto/rsa-pkcs1pad.c | 16 +-
drivers/char/tpm/Kconfig | 1 +
drivers/char/tpm/Makefile | 5 +
drivers/char/tpm/tpm2_key.c | 118 +++
.../char/tpm}/tpm2key.asn1 | 0
include/crypto/rsa-pkcs1pad.h | 20 +
include/crypto/tpm2_key.h | 35 +
include/linux/tpm.h | 2 +
security/keys/trusted-keys/Makefile | 2 -
security/keys/trusted-keys/trusted_tpm2.c | 131 +---
13 files changed, 898 insertions(+), 118 deletions(-)
create mode 100644 crypto/asymmetric_keys/tpm2_key_rsa.c
create mode 100644 drivers/char/tpm/tpm2_key.c
rename {security/keys/trusted-keys => drivers/char/tpm}/tpm2key.asn1 (100%)
create mode 100644 include/crypto/rsa-pkcs1pad.h
create mode 100644 include/crypto/tpm2_key.hSignature · 1 line
2.45.1
Jarkko Sakkinen
maintainerPATCH v4 1/5 crypto: rsa-pkcs1pad: export rsa1_asn_lookup()
ASN.1 template is required for TPM2 asymmetric keys, as it needs to be piggy-packed with the input data before applying TPM2_RSA_Decrypt. This patch prepares crypto subsystem for the addition of those keys.
--- crypto/rsa-pkcs1pad.c | 16 ++++++++++------ include/crypto/rsa-pkcs1pad.h | 20 ++++++++++++++++++++ 2 files changed, 30 insertions(+), 6 deletions(-) create mode 100644 include/crypto/rsa-pkcs1pad.h
crypto/rsa-pkcs1pad.c +10 -6
@@ -7,6 +7,7 @@#include <crypto/algapi.h> #include <crypto/akcipher.h> +#include <crypto/rsa-pkcs1pad.h> #include <crypto/internal/akcipher.h> #include <crypto/internal/rsa.h> #include <linux/err.h>
@@ -79,11 +80,7 @@ static const u8 rsa_digest_info_sha3_512[] = {0x05 ,0x00 ,0x04 ,0x40 }; -static const struct rsa_asn1_template { - const char *name; - const u8 *data; - size_t size; -} rsa_asn1_templates[] = { +static const struct rsa_asn1_template rsa_asn1_templates[] = { #define _(X) { #X, rsa_digest_info_##X, sizeof(rsa_digest_info_##X) }_ (md5), _(sha1),
@@ -101,7 +98,13 @@ static const struct rsa_asn1_template { { NULL } }; -static const struct rsa_asn1_template *rsa_lookup_asn1 (const char *name) +/** +* rsa_lookup_asn1() - Lookup the ASN.1 digest info given the hash +* name: hash algorithm name +* +* Returns the ASN.1 digest info on success, and NULL on failure. +*/ +const struct rsa_asn1_template *rsa_lookup_asn1 (const char *name) {const struct rsa_asn1_template *p;
@@ -110,6 +113,7 @@ static const struct rsa_asn1_template *rsa_lookup_asn1(const char *name)return p;return NULL ; } +EXPORT_SYMBOL_GPL (rsa_lookup_asn1);struct pkcs1pad_ctx {struct crypto_akcipher *child;
include/crypto/rsa-pkcs1pad.h new file +20 -0
@@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* +* RSA padding templates. +*/ + +#ifndef _CRYPTO_RSA_PKCS1PAD_H +#define _CRYPTO_RSA_PKCS1PAD_H + +/* +* Hash algorithm name to ASN.1 template mapping. +*/ +struct rsa_asn1_template { +const char *name; +const u8 *data; +size_t size; +}; + +const struct rsa_asn1_template *rsa_lookup_asn1 (const char *name); + +#endif /* _CRYPTO_RSA_PKCS1PAD_H */
Signature · 1 line
2.45.1
Jarkko Sakkinen
maintainerPATCH v4 2/5 KEYS: trusted: Change -EINVAL to -E2BIG
In reply to Jarkko SakkinenReport -E2BIG instead of -EINVAL when too large size for the key blob is requested.
--- security/keys/trusted-keys/trusted_tpm2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
security/keys/trusted-keys/trusted_tpm2.c +1 -1
@@ -122,7 +122,7 @@ static int tpm2_key_decode(struct trusted_key_payload *payload,return ret;if (ctx.priv_len + ctx.pub_len >MAX_BLOB_SIZE ) -return -EINVAL ; +return -E2BIG ; blob =kmalloc (ctx.priv_len + ctx.pub_len +4 ,GFP_KERNEL );if (!blob)
Signature · 1 line
2.45.1
Jarkko Sakkinen
maintainerPATCH v4 3/5 KEYS: trusted: Move tpm2_key_decode() to the TPM driver
In reply to Jarkko SakkinenMove tpm2_key_decode() to the TPM driver and export the symbols to make them callable from trusted keys. It can re-used for asymmetric keys.
---
v2:
Do not allocate blob twice. Use the one inside struct tpm2_key.
---
drivers/char/tpm/Kconfig | 1 +
drivers/char/tpm/Makefile | 5 +
drivers/char/tpm/tpm2_key.c | 111 +++++++++++++++
.../char/tpm}/tpm2key.asn1 | 0
include/crypto/tpm2_key.h | 33 +++++
security/keys/trusted-keys/Makefile | 2 -
security/keys/trusted-keys/trusted_tpm2.c | 127 +++---------------
7 files changed, 167 insertions(+), 112 deletions(-)
create mode 100644 drivers/char/tpm/tpm2_key.c
rename {security/keys/trusted-keys => drivers/char/tpm}/tpm2key.asn1 (100%)
create mode 100644 include/crypto/tpm2_key.hdrivers/char/tpm/Kconfig +1 -0
@@ -7,6 +7,7 @@ menuconfig TCG_TPM tristate "TPM Hardware Support" depends on HAS_IOMEM imply SECURITYFS + select ASN1 select CRYPTO select CRYPTO_HASH_INFO help
drivers/char/tpm/Makefile +5 -0
@@ -17,6 +17,11 @@ tpm-y += eventlog/tpm1.o tpm-y += eventlog/tpm2.o tpm-y += tpm-buf.o +# TPM2 Asymmetric Key +$(obj)/trusted_tpm2.o: $(obj)/tpm2key.asn1.h +tpm-y += tpm2key.asn1.o +tpm-y += tpm2_key.o + tpm-$(CONFIG_TCG_TPM2_HMAC) += tpm2-sessions.o tpm-$(CONFIG_ACPI) += tpm_ppi.o eventlog/acpi.o tpm-$(CONFIG_EFI) += eventlog/efi.o
drivers/char/tpm/tpm2_key.c new file +111 -0
111 lines not on this page · raw message
drivers/char/tpm/tpm2key.asn1 renamed from security/keys/trusted-keys/tpm2key.asn1 +0 -0
include/crypto/tpm2_key.h new file +33 -0
@@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef __LINUX_TPM2_KEY_H__ +#define __LINUX_TPM2_KEY_H__ + +#include <linux/slab.h> + +/* +* TPM2 ASN.1 key +*/ +struct tpm2_key { +u32 parent; +const u8 *blob; +u32 blob_len; +const u8 *pub; +u32 pub_len; +const u8 *priv; +u32 priv_len; +}; + +int tpm2_key_decode (const u8 *src,u32 src_len,struct tpm2_key *key, +u32 max_key_len); + +/** +* tpm2_key_free() - Release TPM2 asymmetric key resources and reset values +* @key: TPM2 asymmetric key. +*/ +static inline void tpm2_key_destroy (struct tpm2_key *key) +{ +kfree (key->blob); +memset (key,0 ,sizeof (*key)); +} + +#endif /* __LINUX_TPM2_KEY_H__ */
security/keys/trusted-keys/Makefile +0 -2
@@ -7,9 +7,7 @@ obj-$(CONFIG_TRUSTED_KEYS) += trusted.o trusted-y += trusted_core.o trusted-$(CONFIG_TRUSTED_KEYS_TPM) += trusted_tpm1.o -$(obj)/trusted_tpm2.o: $(obj)/tpm2key.asn1.h trusted-$(CONFIG_TRUSTED_KEYS_TPM) += trusted_tpm2.o -trusted-$(CONFIG_TRUSTED_KEYS_TPM) += tpm2key.asn1.o trusted-$(CONFIG_TRUSTED_KEYS_TEE) += trusted_tee.o
security/keys/trusted-keys/trusted_tpm2.c +17 -110
178 lines not on this page · raw message
Signature · 1 line
2.45.1
Jarkko Sakkinen
maintainerPATCH v4 4/5 tpm: tpm2_key: Extend parser to TPM_LoadableKey
In reply to Jarkko SakkinenExtend parser to TPM_LoadableKey. Add field for oid to struct tpm2_key so that callers can differentiate different key types.
---
v3:
* Fixup klog messages:
https://lore.kernel.org/linux-integrity/SN7PR18MB53140F4341BC441C1C11586EE3EA2@SN7PR18MB5314.namprd18.prod.outlook.com/
--- drivers/char/tpm/tpm2_key.c | 17 ++++++++++++----- include/crypto/tpm2_key.h | 2 ++ security/keys/trusted-keys/trusted_tpm2.c | 4 ++++ 3 files changed, 18 insertions(+), 5 deletions(-)
drivers/char/tpm/tpm2_key.c +12 -5
@@ -32,16 +32,23 @@ int tpm2_key_type(void *context, size_t hdrlen, const void *value, size_t vlen) { enum OID oid = look_up_OID(value, vlen); - -if (oid != OID_TPMSealedData) { +struct tpm2_key *key = context; + +switch (oid) { +case OID_TPMSealedData: +pr_debug ("TPMSealedData\n" ); +break ; +case OID_TPMLoadableKey: +pr_debug ("TPMLodableKey\n" ); +break ; +default :char buffer[50 ]; -sprint_oid (value, vlen, buffer,sizeof (buffer)); -pr_debug ("OID is \"%s\" which is not TPMSealedData\n" , - buffer); +pr_debug ("Unknown OID \"%s\"\n" , buffer);return -EINVAL ; } + key->oid = oid;return 0 ; }
include/crypto/tpm2_key.h +2 -0
@@ -2,12 +2,14 @@ #ifndef __LINUX_TPM2_KEY_H__ #define __LINUX_TPM2_KEY_H__ +#include <linux/oid_registry.h> #include <linux/slab.h> /* * TPM2 ASN.1 key */ struct tpm2_key { + enum OID oid; u32 parent; const u8 *blob; u32 blob_len;
security/keys/trusted-keys/trusted_tpm2.c +4 -0
@@ -303,6 +303,10 @@ static int tpm2_load_cmd(struct tpm_chip *chip, payload->old_format =1 ; }else { blob = key.blob; +if (key.oid != OID_TPMSealedData) { +tpm2_key_destroy (&key); +return -EINVAL ; + } }if (!blob)
Signature · 1 line
2.45.1
Jarkko Sakkinen
maintainerPATCH v4 5/5 keys: asymmetric: ASYMMETRIC_TPM2_KEY_RSA_SUBTYPE
In reply to Jarkko SakkinenFrom: James Prestwood <[email protected]>
Based on earlier work by James Prestwood.
Add ASN.1 compatible asymmetric TPM2 RSA key subtype:
1. Signing and decryption (with the private key) is handled by TPM2_RSA_Decrypt.
2. Encryption (with the public key) is handled by the kernel RSA implementation.
---
v4:
* Just put the values to the buffer instead of encoding them.
* Adjust buffer sizes.
* Make tpm2_rsa_key_encode() not to allocate from heap and simplify the serialization.
v3:
* Drop the special case for null handle i.e. do not define policy.
* Remove extra empty line.
v2:
* Remove two spurios pr_info() messsages that I forgot to remove.
* Clean up padding functions and add additional checks for length also in tpm2_unpad_pcks1().
* Add the missing success check kzalloc() in tpm2_key_rsa_decrypt().
* Check that params->out_len for capacity before copying the result.
--- crypto/asymmetric_keys/Kconfig | 15 + crypto/asymmetric_keys/Makefile | 1 + crypto/asymmetric_keys/tpm2_key_rsa.c | 670 ++++++++++++++++++++++++++ include/linux/tpm.h | 2 + 4 files changed, 688 insertions(+) create mode 100644 crypto/asymmetric_keys/tpm2_key_rsa.c
crypto/asymmetric_keys/Kconfig +15 -0
@@ -15,6 +15,7 @@ config ASYMMETRIC_PUBLIC_KEY_SUBTYPE select MPILIB select CRYPTO_HASH_INFO select CRYPTO_AKCIPHER + select CRYPTO_RSA select CRYPTO_SIG select CRYPTO_HASH help
@@ -23,6 +24,20 @@ config ASYMMETRIC_PUBLIC_KEY_SUBTYPE appropriate hash algorithms (such as SHA-1) must be available. ENOPKG will be reported if the requisite algorithm is unavailable. +config ASYMMETRIC_TPM2_KEY_RSA_SUBTYPE + tristate "Asymmetric TPM2 RSA crypto algorithm subtype" + depends on TCG_TPM + select TCG_TPM2_HMAC + select CRYPTO_RSA + select CRYPTO_SHA256 + select CRYPTO_HASH_INFO + select ASN1 + help + This option provides support for asymmetric TPM2 key type handling. + If signature generation and/or verification are to be used, + appropriate hash algorithms (such as SHA-256) must be available. + ENOPKG will be reported if the requisite algorithm is unavailable. + config X509_CERTIFICATE_PARSER tristate "X.509 certificate parser" depends on ASYMMETRIC_PUBLIC_KEY_SUBTYPE
crypto/asymmetric_keys/Makefile +1 -0
@@ -11,6 +11,7 @@ asymmetric_keys-y := \ signature.o obj-$(CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE) += public_key.o +obj-$(CONFIG_ASYMMETRIC_TPM2_KEY_RSA_SUBTYPE) += tpm2_key_rsa.o # # X.509 Certificate handling
crypto/asymmetric_keys/tpm2_key_rsa.c new file +670 -0
670 lines not on this page · raw message
include/linux/tpm.h +2 -0
@@ -43,6 +43,7 @@ enum tpm2_session_types {/* if you add a new hash to this, increment TPM_MAX_HASHES below */ enum tpm_algorithms {TPM_ALG_ERROR =0x0000 , +TPM_ALG_RSA =0x0001 ,TPM_ALG_SHA1 =0x0004 ,TPM_ALG_AES =0x0006 ,TPM_ALG_KEYEDHASH =0x0008 ,
@@ -271,6 +272,7 @@ enum tpm2_command_codes {TPM2_CC_NV_READ =0x014E ,TPM2_CC_CREATE =0x0153 ,TPM2_CC_LOAD =0x0157 , +TPM2_CC_RSA_DECRYPT =0x0159 ,TPM2_CC_SEQUENCE_UPDATE =0x015C ,TPM2_CC_UNSEAL =0x015E , TPM2_CC_CONTEXT_LOAD = 0x0161,
Signature · 1 line
2.45.1