Commit f2219745 authored by James Bottomley's avatar James Bottomley Committed by Jarkko Sakkinen
Browse files

security: keys: trusted: use ASN.1 TPM2 key format for the blobs



Modify the TPM2 key format blob output to export and import in the
ASN.1 form for TPM2 sealed object keys.  For compatibility with prior
trusted keys, the importer will also accept two TPM2B quantities
representing the public and private parts of the key.  However, the
export via keyctl pipe will only output the ASN.1 format.

The benefit of the ASN.1 format is that it's a standard and thus the
exported key can be used by userspace tools (openssl_tpm2_engine,
openconnect and tpm2-tss-engine).  The format includes policy
specifications, thus it gets us out of having to construct policy
handles in userspace and the format includes the parent meaning you
don't have to keep passing it in each time.

This patch only implements basic handling for the ASN.1 format, so
keys with passwords but no policy.

Signed-off-by: default avatarJames Bottomley <James.Bottomley@HansenPartnership.com>
Tested-by: default avatarJarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: default avatarJarkko Sakkinen <jarkko@kernel.org>
parent de66514d
Loading
Loading
Loading
Loading
+58 −0
Original line number Diff line number Diff line
@@ -207,3 +207,61 @@ about the usage can be found in the file
Another new format 'enc32' has been defined in order to support encrypted keys
with payload size of 32 bytes. This will initially be used for nvdimm security
but may expand to other usages that require 32 bytes payload.


TPM 2.0 ASN.1 Key Format
------------------------

The TPM 2.0 ASN.1 key format is designed to be easily recognisable,
even in binary form (fixing a problem we had with the TPM 1.2 ASN.1
format) and to be extensible for additions like importable keys and
policy::

    TPMKey ::= SEQUENCE {
        type		OBJECT IDENTIFIER
        emptyAuth	[0] EXPLICIT BOOLEAN OPTIONAL
        parent		INTEGER
        pubkey		OCTET STRING
        privkey		OCTET STRING
    }

type is what distinguishes the key even in binary form since the OID
is provided by the TCG to be unique and thus forms a recognizable
binary pattern at offset 3 in the key.  The OIDs currently made
available are::

    2.23.133.10.1.3 TPM Loadable key.  This is an asymmetric key (Usually
                    RSA2048 or Elliptic Curve) which can be imported by a
                    TPM2_Load() operation.

    2.23.133.10.1.4 TPM Importable Key.  This is an asymmetric key (Usually
                    RSA2048 or Elliptic Curve) which can be imported by a
                    TPM2_Import() operation.

    2.23.133.10.1.5 TPM Sealed Data.  This is a set of data (up to 128
                    bytes) which is sealed by the TPM.  It usually
                    represents a symmetric key and must be unsealed before
                    use.

The trusted key code only uses the TPM Sealed Data OID.

emptyAuth is true if the key has well known authorization "".  If it
is false or not present, the key requires an explicit authorization
phrase.  This is used by most user space consumers to decide whether
to prompt for a password.

parent represents the parent key handle, either in the 0x81 MSO space,
like 0x81000001 for the RSA primary storage key.  Userspace programmes
also support specifying the primary handle in the 0x40 MSO space.  If
this happens the Elliptic Curve variant of the primary key using the
TCG defined template will be generated on the fly into a volatile
object and used as the parent.  The current kernel code only supports
the 0x81 MSO form.

pubkey is the binary representation of TPM2B_PRIVATE excluding the
initial TPM2B header, which can be reconstructed from the ASN.1 octet
string length.

privkey is the binary representation of TPM2B_PUBLIC excluding the
initial TPM2B header which can be reconstructed from the ASN.1 octed
string length.
+1 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ struct trusted_key_payload {
	unsigned int key_len;
	unsigned int blob_len;
	unsigned char migratable;
	unsigned char old_format;
	unsigned char key[MAX_KEY_SIZE + 1];
	unsigned char blob[MAX_BLOB_SIZE];
};
+3 −0
Original line number Diff line number Diff line
@@ -75,6 +75,9 @@ config TRUSTED_KEYS
	select CRYPTO_HMAC
	select CRYPTO_SHA1
	select CRYPTO_HASH_INFO
	select ASN1_ENCODER
	select OID_REGISTRY
	select ASN1
	help
	  This option provides support for creating, sealing, and unsealing
	  keys in the kernel. Trusted keys are random number symmetric keys,
+3 −0
Original line number Diff line number Diff line
@@ -5,4 +5,7 @@

obj-$(CONFIG_TRUSTED_KEYS) += trusted.o
trusted-y += trusted_tpm1.o

$(obj)/trusted_tpm2.o: $(obj)/tpm2key.asn1.h
trusted-y += trusted_tpm2.o
trusted-y += tpm2key.asn1.o
+11 −0
Original line number Diff line number Diff line
---
--- ASN.1 for TPM 2.0 keys
---

TPMKey ::= SEQUENCE {
	type		OBJECT IDENTIFIER ({tpm2_key_type}),
	emptyAuth	[0] EXPLICIT BOOLEAN OPTIONAL,
	parent		INTEGER ({tpm2_key_parent}),
	pubkey		OCTET STRING ({tpm2_key_pub}),
	privkey		OCTET STRING ({tpm2_key_priv})
	}
Loading