tpm2-software / tpm2-tss-engine

OpenSSL Engine for TPM2 devices
https://tpm2-software.github.io
BSD 3-Clause "New" or "Revised" License
151 stars 100 forks source link

Document interoperability requirements on the ephemeral primary keys #230

Closed dwmw2 closed 3 years ago

dwmw2 commented 3 years ago

We don't get to mess with these.

Signed-off-by: David Woodhouse dwmw2@infradead.org

dwmw2 commented 3 years ago

Drawing this out of the comment for discussion...

     * However, it may not be interoperable to do so, and it isn't a
     * good idea anyway since RSA keys are *slow* to generate, so
     * users with a broken TPM like this really *should* have followed
     * the recommendation to create the RSA primary and store it in
     * the NVRAM at 0x81000001. And then the TSS2 PEM keys should use
     * *that* as the parent, not the ephemeral version. In fact, there
     * is a strong case to be made for defaulting to 0x81000001 if it
     * exists, *before* (or never) falling back to generating an RSA
     * key here.

Indeed, there is a lot to be said for using the key at NVRAM index 0x81000001 if the TPM doesn't support ECC. I don't have very strong feelings about it; after all, anyone who has followed the recommendation to store the RSA key at 0x81000001 can also create their TSS2-PEM key explicitly asking for that to be used as the parent, so it's not like we are denying them the option of doing so.

If I was doing this myself I might have used AES-256 instead of AES-128. Thankfully, however, I didn't do this myself without co-ordination or we would have ended up with an incompatibility instead of just this engine supporting something that the others don't.

At this point I think we need to accept it as a fait accompli and implement the same thing in @jejb's engine, in OpenConnect, and in GnuTLS — where @ueno is now adding support, except that this had morphed into using RSA primaries for all RSA child keys even when the TPM does support ECC, which was definitely broken (and caught in review).

Didn't WolfSSL also add support for TSS2 PEM files? @dgarske?

ueno commented 3 years ago

If I'm following the discussions correctly, I see quite a few implications of using this format. Perhaps it might make sense to standardize it in referencible form (for example, as an internet draft)? I can try to create an initial draft for review.

dwmw2 commented 3 years ago

Oh $DEITY yes please. @jejb didn't you start on that at one point?

AndreasFuchsTPM commented 3 years ago

Internet draft or TCG spec ? Don't we use TCG OIDs ?

dwmw2 commented 3 years ago

Yes, we do use TCG OIDs. I'd settle for either an I-D or TCG spec; writing something up is important though.

jejb commented 3 years ago

On Wed, 2021-09-29 at 06:02 -0700, David Woodhouse wrote:

Yes, we do use TCG OIDs. I'd settle for either an I-D or TCG spec; writing something up is important though.

I started writing an RFC but I couldn't get anyone to review it. This is what I have so far. Section 3.1.5 exactly covers this problem because it says for MSO 40 parents the primary generation must be EC. Perhaps if I insert it here, people might actually look at it ...


Network Working Group J. Bottomley Internet-Draft Linux Kernel Intended status: Informational May 2021 Expires: 23 November 2021

           ASN.1 Specification for TPM 2.0 Key Files
                  draft-bottomley-tpm-keys-00

Abstract

This specification is designed ot be an extension to the ASN.1 (defined in [X.680]) specification of PKCS #1 [RFC8017] to define the file format of private keys that need to be loaded into a TPM 2 device to operate.

Status of This Memo

This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.

Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet- Drafts is at https://datatracker.ietf.org/drafts/current/.

Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."

This Internet-Draft will expire on 2 November 2021.

Copyright Notice

Copyright (c) 2021 IETF Trust and the persons identified as the document authors. All rights reserved.

This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/ license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Simplified BSD License.

Bottomley Expires 23 November 2021 [Page 1] Internet-Draft TPM 2 Key Format May 2021

Table of Contents

  1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 2
  2. Terminology . . . . . . . . . . . . . . . . . . . . . . . . . 2 2.1. Notation . . . . . . . . . . . . . . . . . . . . . . . . 2
  3. Key Representation . . . . . . . . . . . . . . . . . . . . . 3 3.1. TPMkey Syntax . . . . . . . . . . . . . . . . . . . . . . 3 3.1.1. type . . . . . . . . . . . . . . . . . . . . . . . . 4 3.1.2. emptyAuth . . . . . . . . . . . . . . . . . . . . . . 4 3.1.3. policy . . . . . . . . . . . . . . . . . . . . . . . 4 3.1.4. secret . . . . . . . . . . . . . . . . . . . . . . . 4 3.1.5. parent . . . . . . . . . . . . . . . . . . . . . . . 5 3.1.6. pubkey . . . . . . . . . . . . . . . . . . . . . . . 5 3.1.7. privkey . . . . . . . . . . . . . . . . . . . . . . . 5
  4. Key Policy Specification . . . . . . . . . . . . . . . . . . 5 4.1. TPMPolicy Syntax . . . . . . . . . . . . . . . . . . . . 6 4.1.1. CommandCode . . . . . . . . . . . . . . . . . . . . . 6 4.1.2. CommandPolicy . . . . . . . . . . . . . . . . . . . . 6 4.2. Policy Implementation Considerations . . . . . . . . . . 6 4.2.1. Authorization Policy . . . . . . . . . . . . . . . . 6
  5. Normative References . . . . . . . . . . . . . . . . . . . . 7 Author's Address . . . . . . . . . . . . . . . . . . . . . . . . 7
  1. Introduction

    The Security of private keys has long been a concern and the ability of ubiquitous devices like TPMs has made it useful to use them for secure private key storage. With the advent of TPM 2.0, private key storage inside the TPM (acting as a token which could be referred to by PKCS #11) has been discouraged, and instead key files which are loaded and evicted as necessary is the encouraged format. This standard defines an interoperable ASN.1 representation for such key files, so that a key created by one tool should be loadable by a different one.

  2. Terminology

    The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC2119].

2.1. Notation

ASN.1 Abstract Syntax Notatition defined in [X.680]

DER Distinguished Encoding Rules. Basically a defined binary representation for ASN.1

Bottomley Expires 23 November 2021 [Page 2] Internet-Draft TPM 2 Key Format May 2021

MSO Most Significant Octet (the highest order byte of an integer)

PEM Privacy enhanced Electronic Mail. An ASCII compatible representation of DER

TCG Trusted Computing Group

TPM Trusted Platform Module

  1. Key Representation

    All TPM 2.0 keys consist of two binary pieces, a public part, which can be parsed according to the TPM specification for TPM2B_PUBLIC [TPM2.0] and a private part, which is cryptographically sealed in such a way as to be only readable on the TPM that created it. The purpose of this specification is to specify a format by which the public and private pieces of a TPM key can be loaded.

    The design of the TPMkey ASN.1 format is that it should have a distinguishing OID at the beginning so the DER/BER form of the key can be easily recognized. In PEM form, the key MUST have "-----BEGIN TSS2 PRIVATE KEY-----" and "-----END TSS2 PRIVATE KEY-----" as the PEM guards. All additional information that may be needed to load the key is specified as optional explicit elements, which can be extended by later specifications, which is why the TPMkey is not versioned.

3.1. TPMkey Syntax

TPMKey ::= SEQUENCE {
   type        OBJECT IDENTIFIER
   emptyAuth   [0] EXPLICIT BOOLEAN OPTIONAL
   policy      [1] EXPLICIT SEQUENCE OF TPMPolicy OPTIONAL
   secret      [2] EXPLICIT OCTET STRING OPTIONAL
   parent      INTEGER
   pubkey      OCTET STRING
   privkey     OCTET STRING
 }

The fields of type TPMKey have the following meanings:

Bottomley Expires 23 November 2021 [Page 3] Internet-Draft TPM 2 Key Format May 2021

3.1.1. type

A unique OID specifying the key type. This standard currently defines three types of keys: a loadable key, specified by id- loadablekey, (to be loaded with TPM2_Load), an importable key, specified by id-importablekey, (to be loaded with TPM2_Import) and a sealed data key, specified by id-sealedkey, (to be extracted with TPM2_Unseal). The TCG has reserved the following OID prefix for this:

 id-tpmkey OBJECT IDENTIFIER ::=
   {joint-iso-itu-t(2) international-organizations(23) 133 10}

And the three key types are:

 id-loadablekey OBJECT IDENTIFIER ::=
   {id-tpmkey 3}

 id-importablekey OBJECT IDENTIFIER ::=
   {id-tpmkey 4}

 id-sealedkey OBJECT IDENTIFIER ::=
   {id-tpmkey 5}

3.1.2. emptyAuth

An implementation needs to know as it formulates the TPM2_Load/Import/Unseal command whether it must also send down an authorization, so this parameter gives that indication. emptyAuth MUST be true if authorization is NOT required and MUST BE either false or absent if authorization is required. Since this element has three states (one representing true and two representing false) it is RECOMMENDED that implementations emitting TPMkey representations use absence of the tag to represent false. However, implementations reading TPMKey MUST be able to process all three possible states.

3.1.3. policy

This MUST be present if the TPM key has a policy hash because it describes to the implementation how to construct the policy. The forms of the policy statement are described in section Section 4.

3.1.4. secret

This section describes the additional cryptographic secret used to specify the outer wrapping of an importable key. It MUST be present for key type id-importablekey and MUST NOT be present for any other key type.

Bottomley Expires 23 November 2021 [Page 4] Internet-Draft TPM 2 Key Format May 2021

3.1.5. parent

This MUST be present for all keys and specifies the parent key. The parent key SHOULD be either a persistent handle (MSO 0x81) or a permanent handle (MSO 0x40). Since volatile handle numbering can change unexpectedly depending on key load order, the parent SHOULD NOT be a volatile handle (MSO 0x80). The parent MAY NOT be any other MSO.

If a permanent handle (MSO 0x40) is specified then the implementation MUST run TPM2_CreatePrimary on the handle using the TCG specified Elliptic Curve template for the NIST P-256 curve and use the primary key so generated as the parent.

3.1.6. pubkey

This MUST be present and MUST correspond to the fully marshalled TPM2B_PUBLIC structure of the TPM Key with the exception that the leading U16 parameter specifying size MUST BE omitted (it is redundant, since all ASN.1 structures are length specified).

3.1.7. privkey

This MUST be present and MUST correspond to the fully marshalled TPM2B_PRIVATE structure of the TPM Key with the exception that the leading U16 parameter specifying size MUST BE omitted (it is redundant, since all ASN.1 structures are length specified).

  1. Key Policy Specification

    Policy is constructed on a TPM by executing a sequence of policy statements. This specification currently only defines a limited subset of the allowed policy statements. The policy is specified by a hash, which the execution of the policy statements must reach in order for the policy to be validated (See [TPM2.0] Part 1 for a detailed description.

    The TPMPolicy ASN.1 MUST be a sequence of policy statements which correspond exactly to TPM policy instructions in the order they should be executed and additionally from which the ultimate policy hash can be constructed.

    The current policy specification is strictly for AND based policy only and may be extended at a later date with OR policy. However, the ASN.1 for policy is fomulated as CONS elements, leaving the possibility of adding additional but optional elements for policy statements which are not supported by this standard (such as TPM2_PolicyAuthorize).

Bottomley Expires 23 November 2021 [Page 5] Internet-Draft TPM 2 Key Format May 2021

4.1. TPMPolicy Syntax

TPMPolicy ::= SEQUENCE {
   CommandCode   [0] EXPLICIT INTEGER
   CommandPolicy [1] EXPLICIT OCTET STRING
 }

The Fields of type TPMPolicy have the following meanings:

4.1.1. CommandCode

This is the integer representation of the TPM command code for the policy statement.

4.1.2. CommandPolicy

This is a binary string representing a fully marshalled, TPM ordered, command body for the TPM policy command. Therefore to send the command, the implementation simply marshalls the command code and appends this octet string as the body.

Commands which have no body, such as TPM2_AuthVal, MUST be specified as a zero length OCTET STRING

4.2. Policy Implementation Considerations

The policy hash for AND based policies is constructed by extension of the prior policy hash

 newHash = HASH ( oldHash || policyHash )

where policyHash is usually simply the hash of the fully marshalled policy command (including the CommandCode). However, this isn't true for TPM2_PolicyCounterTimer() so always consult the [TPM2.0] specifications for how to construct the policyHash.

4.2.1. Authorization Policy

When Authorization (Passing in a password) is required, the emptyAuth parameter MUST be absent or set to false and additionally the TPM_CC_PolicyAuthValue MUST be specified as the command code for one entry in the TPMPolicy sequence. However, the implementation MAY choose to execute either TPM2_PolicyPassword for TPM_RS_PW or TPM2_PolicyAuthValue for HMAC based authorization depending on whether the command being authorized is using sessions or not. If the policy does not require an authorization then the emptyAuth parameter MUST be set to true.

Bottomley Expires 23 November 2021 [Page 6] Internet-Draft TPM 2 Key Format May 2021

  1. Normative References

    [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997, https://www.rfc-editor.org/info/rfc2119;.

    [RFC8017] Moriarty, K., Ed., Kaliski, B., Jonsson, J., and A. Rusch, "PKCS #1: RSA Cryptography Specifications Version 2.2", RFC 8017, DOI 10.17487/RFC8017, November 2016, https://www.rfc-editor.org/info/rfc8017;.

    [TPM2.0] TCG, ., "TPM 2.0 Library Specification", 15 March 2013, https://trustedcomputinggroup.org/resource/tpm-library- specification/.

    [X.680] ITU, "ITU-T Recommendation X.680, Information technology - Abstract Syntax Notation One (ASN.1): Specification of basic notation.", August 2015, https://www.itu.int/rec/T-REC-X.680-201508-I/en;.

Author's Address

James E.J. Bottomley Linux Kernel United States of America

Email: @.***

Bottomley Expires 23 November 2021 [Page 7]

ueno commented 3 years ago

@jejb thank you for sharing, that looks great! I see a slight difference in the TPMKey definition from the one used in the engine (the policy and secret fields). If it is okay to extend the format, I have a couple of questions/suggestions:

AndreasFuchsTPM commented 3 years ago

I agree that a common standard would be great. IMHO, when using TCG OIDs it would have to be a TCG spec, right ?

As for what I'd want on a common standard is the ability to express policies in the TCG's language for policies which is some more versatile: https://trustedcomputinggroup.org/wp-content/uploads/TSS_JSON_Policy_v0.7_r04_pubrev.pdf

jejb commented 3 years ago

On Wed, 2021-09-29 at 08:39 -0700, Daiki Ueno wrote:

@jejb thank you for sharing, that looks great! I see a slight difference in the TPMKey definition from the one used in the engine (the policy and secret fields). If it is okay to extend the format, I have a couple of questions/suggestions:

We can extend the format, but the extension must remain backward compatible with the previous one because there are already implementations in the field. Mostly the way to do this is to add additionally numbered explicit optional parameters (like policy and secret).

  • could it store parameters of the generated parent (algorithm, curve, hash, etc), for algorithm agility?

It could (basically this would mean storing the parent key template), but I don't really see any point to doing that. The only use the parent has is the AES symmetric key that protects the child. That means that all the trouble you go to to generate the asymmetric key (which TPM2_CreatePrimary has to do) is wasted. Effectively the parameters are simply inputs to the KDF used to generate the symmetric key. The only algorithm agility you get is in the part you ignore, so it seems simpler to stick with a mandatory template that all TPMs should have. If there ever came a time p-256 got deprecated, then we could add this.

  • could parent be defined as a CHOICE to distinguish volatile and generated keys more explicitly?

I don't think so because that wouldn't be backward compatible with the current spec. Plus the MSO already does this, so what would the additional benefit be?

James

dwmw2 commented 3 years ago

I think @gotthardp is another interested party, having an implementation in https://github.com/tpm2-software/tpm2-openssl

williamcroberts commented 3 years ago

We also use the PEM format in tpm2-pytss and tpm2-pkcs11 so we get interoperability between the projects.

dgarske commented 3 years ago

@dwmw2: Yes we added PEM support in wolfTPM for the KeyGen example here: https://github.com/wolfSSL/wolfTPM/blob/master/examples/keygen/keygen.c#L49 PR: https://github.com/wolfSSL/wolfTPM/pull/174

dwmw2 commented 3 years ago

@dwmw2: Yes we added PEM support in wolfTPM for the KeyGen example here: https://github.com/wolfSSL/wolfTPM/blob/master/examples/keygen/keygen.c#L49 PR: wolfSSL/wolfTPM#174

Hm, I don't see the -----BEGIN TSS2 PRIVATE KEY----- anywhere there? We're talking about this one:

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