Scroll to navigation

CREATE_TPM2_KEY(1) User Commands CREATE_TPM2_KEY(1)

NAME

create_tpm2_key - create tpm2 loadable key

SYNOPSIS

create_tpm2_key [options] <filename>

DESCRIPTION

Can be used to create a TPM loadable representation of a private key. The key is either internal to the TPM or wrapped from an existing private key.

Note that this command can now create two different types of keys: importable and loadable (the default type being loadable). The difference between the two is that the creation of loadable keys requires the presence of the actual TPM the key will be loaded on. An importable key can be created without any TPM contact provided you have the public key of the parent the new key will be imported to.

OPTIONS

require a password for the key [NO]
Specify the parent key password (default EmptyAuth)
mark the key as having Dictionary Attack implications. This means that if the key password is incorrectly presented too many times, the TPM may Implement DA mitigation and refuse connections for a while
print this help message
key size in bits [2048]
name algorithm to use sha1 [sha256] sha384 sha512
parent for the key, can either be a persistent key or a hierarchy. the hierarchies can be 'platform', 'owner', 'null' or 'endorsement'. The seeds used for derivation are platform, storage, null or endorsement respectively
print package version
wrap an existing openssl PEM key. <file> can be in either PKCS12 or OpenSSL standard PEM private key form (PKCS1 or PKCS8)
use this password instead of prompting
create an RSA key (the default)
Create an ECC key using the specified curve. Supported curves are bnp256, nisp256, nisp384
List all the Elliptic Curves the TPM supports
Specify a policy for the TPM key
Create an importable key with the outer wrapper encrypted to <pubkey>
Create a restricted key. A restricted key may not be used for general signing or decryption but may be the parent of other keys (i.e. it is a storage key)
Lock the created key to the specified PCRs By current value. See PCR VALUES for details about formatting
Can only be used in a set of localities described by the <loc> bitmap
Add a signed policy directive that allows policies signed by the specified public <key> to authorize use of the key
Tie authorization of the key to the Authorization of a different object Identified by <handle>.

PCR VALUES

The PCR values are specified as


<bank>:<list>

Where <bank> is any supported PCR hash bank and list specifies the PCRs to lock the key to as both comma separated individual values as well as comma separated ranges. So


sha256:1,3 means PCRs 1 and 3 in the sha256 bank


sha512:1,3-5 means PCRs 1,3,4 and 5 in the sha512 bank

IMPORT

In some cases, there may be a need to wrap a key without access to the TPM it will be use on. For these cases an importable key may be specified with the --import option. For this to work, you must use a public key corresponding exactly to the one the importing TPM will use (Note: only Elliptic Curve parents are currently supported). For instance the owner seed elliptic curve storage key may be produced as

tsscreateprimary -hi o -st -ecc nistp256 -opem parent.pub

Then an importable key may be wrapped to the TPM via:

create_tpm2_key --import parent.pub --wrap key.priv key.tpm

Note that certain parameters must be assumed about a parent when it is wrapped, like the template (must be standard restricted decryption key) and the name hash (must be sha256).

SECRETS IN OTHER OBJECTS

When the option --secrets <handle> is used, it creates a key whose authorization password is conditioned on the password of a different object identified by <handle>. Usually this is a permanent NV index, but could be any object. The design of this policy is to allow the password to be changed without updating the key (simply by changing the authorization of the other object). Because OpenSSL can only request a single password, keys with a --secret policy may not additionally have an --auth option to also require passing in the password embedded in the key.

SIGNED POLICIES

When the option --signed-policy <key> is used, it creates a key whose policy can be extended by anyone possessing the private part of <key>. The <key> presented must be a public key (so the owner of the private key doesn't have to be the owner of the created tpm key).

Note that keys created with --signed-policy cannot be used until at least one signed policy is added.

FILES

Policy File Format

The policy file should contain a rule for each line, where rules can be generated for example with the tsspolicymakerpcr tool from IBM TSS.

Example (PolicyPCR):

$ tsspolicymakerpcr -bm 10000 -if policypcr16aaasha256.txt -v -pr -of policies/policypcr.txt >> policy.txt

where policypcr16aaasha256.txt contains the desired value of PCR 16.

Example (PolicyAuthValue):

$ echo 0000016b >> policy.txt

EXAMPLES

Create a self-signed cert using the TPM engine:

0. Good practice is to generate the RSA version of the primary storage
seed and place it at well known location 81000001 (Microsoft Spec).
To do this, you need to manipulate the non resource manager
interface so the keys aren't lost when the process dies:


# TPM_DEVICE=/dev/tpm0 tsscreateprimary -hi o -st -rsa
Handle 80000000
# TPM_DEVICE=/dev/tpm0 tssevictcontrol -hi o -ho 80000000 -hp 81000001
# TPM_DEVICE=/dev/tpm0 tssflushcontext -ha 80000000


where 80000000 is the the handle and is always returned by the
first command. You must do the final tssflushcontext otherwise the
transient key won't get flushed since you used the non resource
manager interface.


Note: tsscreateprimary will take a while to run (50s on my laptop)
while the TPM derivces an RSA key from the primary seed. This long
time is why you want to store a permanent copy of the derived key.

1. Generate an external key and wrap it for the TPM:
$ openssl genrsa 2048 > <private key>
$ create_tpm2_key -w <private key> [-p 81000001] <key file>


Note: specifying the parent is optional (and you need to have
created it in step 0) but if you leave it out, the key will still
end up parented to the primary storage seed and the TPM will have
to re-derive the ECC version of that seed each time you use it


Note: because the RSA private key is sent to the TPM encrypted, the
tss has to have access to the public part of the parent key (if you
didn't specify a parent, this public part will be created when the
parent key is derived from the storage primary seed), so you may
need to do tssreadpublic -p 81000001 before it will work.

2. Make the openssl certificate request:
$ openssl req -keyform engine -engine tpm2 -key <key file> -new -x509 -days 365 -out <certfilename>

3. Test using openssl:
$ openssl s_server -cert <certfilename> -www -accept 4433 -keyform engine -engine tpm2 -key <keyfilename>

Creating an importable key:

1. First get the public key of the storage primary seed (as an elliptic
curve key):
$ tsscreateprimary -ecc nistp256 -hi o -opem srk.pub

2. Once you have this public key, you can export it anywhere and do the
key wrapping
$ create_tpm2_key --import srk.pub --wrap my_key.priv my_key.tpm

AUTHOR

Written by James Bottomley <James.Bottomley@HansenPartnership.com>

REPORTING BUGS

Report bugs to <openssl-tpm2-engine@groups.io>

COPYRIGHT

Copyright 2017 by James Bottomley License LGPL-2.1-only

April 2024 create_tpm2_key 4.1.2