File: keys.md

package info (click to toggle)
tpm2-openssl 1.3.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,172 kB
  • sloc: ansic: 6,075; sh: 5,400; makefile: 152
file content (250 lines) | stat: -rw-r--r-- 9,963 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
# Key Operations

## Key Management

The tpm2 provider implements a
[OSSL_OP_KEYMGMT](https://www.openssl.org/docs/manmaster/man7/provider-keymgmt.html)
operation for creation and manipulation of TPM-based
[RSA](https://www.openssl.org/docs/manmaster/man7/RSA.html),
[RSA-PSS](https://www.openssl.org/docs/manmaster/man7/RSA-PSS.html)
or EC keys.
These can be used via the EVP_PKEY
[RSA](https://www.openssl.org/docs/manmaster/man7/EVP_PKEY-RSA.html) or
[EC](https://www.openssl.org/docs/manmaster/man7/EVP_PKEY-EC.html)
API functions and the
[`openssl genpkey`](https://www.openssl.org/docs/manmaster/man1/openssl-genpkey.html)
command.

**Subject to TPM resource limits.** Every private EVP_PKEY maintains a transient
sequence object within the TPM memory. The resource manager will not allow
creation of more concurrent objects than `TPM_PT_HR_TRANSIENT_MIN`.

### Key Generation

The following public key algorithms are supported:

| key     | X.509 OID      |
| ------- | -------------- |
| RSA     | rsaEncryption  |
| RSA-PSS | id-RSASSA-PSS  |
| EC      | id-ecPublicKey |

The RSA-PSS key is a restricted version of RSA which only supports signing,
verification and key generation using the PSS padding scheme.

Settable key generation parameters (`-pkeyopt`):
 * `digest` (utf8_string) associates the key with a specific hash.
 * `user-auth` (utf8_string) defines a password, which will be used to authorize
   private key operations.
 * `parent` (uint32) defines parent of the key (as a hex number),
   by default 0x40000001 (TPM2_RH_OWNER).
 * `parent-auth` (utf8_string) defines an (optional) parent password. **Note** That in
    instances where the invoking command flow does not support `-pkeyopt` an environment
    variable `TPM2OPENSSL_PARENT_AUTH` may be used. The `-pkeyopt` `parent-auth`
    overrides the environment variable in instances where they are both set.

The RSA or RSA-PSS keys support also:
 * `bits` (size_t) defines a desired size of the key.
 * `e` (integer) defines a public exponent, by default 65537 (0x10001).

For example, to define a 1024-bit RSA key without authorization under
TPM2_RH_OWNER:
```
openssl genpkey -provider tpm2 -algorithm RSA -pkeyopt bits:1024 -out testkey.priv
```

The EC keys support the following key generation parameters:
 * `group` (utf8_string) specifies the curve to be used. You may use either the
   NIST names or the short OID names:

   | NIST    | OID name   | TPM2               |
   | ------- | ---------- | ------------------ |
   | P-192   | prime192v1 | TPM2_ECC_NIST_P192 |
   | P-224   | secp224r1  | TPM2_ECC_NIST_P224 |
   | P-256   | prime256v1 | TPM2_ECC_NIST_P256 |
   | P-384   | secp384r1  | TPM2_ECC_NIST_P384 |
   | P-521   | secp521r1  | TPM2_ECC_NIST_P521 |

To create an EC key with the P-256 curve, protected by the password `abc`:
```
openssl genpkey -provider tpm2 -algorithm EC -pkeyopt group:P-256 \
    -pkeyopt user-auth:abc -out testkey.priv
```

You may use the `EC PARAMETERS` file, but only the curve name is allowed:
```
openssl ecparam -name prime256v1 -out testparam.pem
openssl genpkey -provider tpm2 -provider base -paramfile testparam.pem -out testkey.priv
```

You may also generate the key using standard TPM2 tools and then make the key
persistent under a given handle using `tpm2_evictcontrol`. For example to create
a new key Attestation Key (AK) with a handle 0x81000000:
```
tpm2_createek -G rsa -c ek_rsa.ctx
tpm2_createak -C ek_rsa.ctx -G rsa -g sha256 -s rsassa -c ak_rsa.ctx
tpm2_evictcontrol -c ak_rsa.ctx 0x81000000
```

Keys restricted to `rsapss` will be handled as RSA-PSS, all other keys as RSA.

### Key Parameter Retrieval

The following parameters of the generated EVP_PKEY can be retrieved from an
RSA or RSA-PSS key (via API only):
 * `bits` (integer), size of the key
 * `max-size` (integer) of the signature
 * `n` (integer), the RSA modulus
 * `e` (integer), the RSA exponent

The modulus can be displayed using:
```
openssl rsa -provider tpm2 -provider base -in testkey.priv -modulus -noout
```

Similarly, the following parameters can be retrieved from an EC key:
 * `group` (utf8_string) short OID name of the curve used
 * `bits` (integer), size of one key coordinate
 * `max-size` (integer) of the signature
 * `pub` (octet_string) public key with both x and y encoded
 * `x` and `y` (integer) individual components of the public key

The EC key also supports retrieval of the entire curve definition:
 * `p` (integer) defines the finite field
 * `a` and `b` (integer) define the elliptic curve
 * `generator` (octet_string) is the (encoded) base point G
 * `order` (integer) of G
 * `cofactor` (integer)

Naturally, parameters of the private key cannot be retrieved from any key.


## Storing the Private or a Public Key

The tpm2 provider implements several
[OSSL_OP_ENCODER](https://www.openssl.org/docs/manmaster/man7/provider-encoder.html)
operations for converting the generated (or loaded) key to various formats.
These can be used via the
[OSSL_ENCODER](https://www.openssl.org/docs/manmaster/man3/OSSL_ENCODER.html)
API functions and the
[`openssl pkey`](https://www.openssl.org/docs/manmaster/man1/openssl-pkey.html)
command.

The following encoders are supported:

| structure            | type                     | openssl arguments
| -------------------- | ------------------------ | -------------------------------- |
| PrivateKeyInfo       | PEM (`TSS2 PRIVATE KEY`) | (default)                        |
| PrivateKeyInfo       | DER                      | `-outform der`                   |
| SubjectPublicKeyInfo | PEM (`PUBLIC KEY`)       | `-pubout`                        |
| SubjectPublicKeyInfo | DER                      | `-pubout -outform der`           |
| PKCS1                | PEM (`RSA PUBLIC KEY`)   | `-RSAPublicKey_out`              |
| PKCS1                | DER                      | `-RSAPublicKey_out -outform der` |
| (null)               | text                     | `-text -noout`                   |

The `TSS2 PRIVATE KEY` file is protected by the TPM and cannot be used on another machine.

To export the X.509 SubjectPublicKeyInfo in PEM (`PUBLIC KEY`), which is the most
common public key format, do:
```
openssl pkey -provider tpm2 -provider base -in testkey.priv -pubout -out testkey.pub
```

To print private key attributes you can use the `-text` argument:
```
openssl rsa -provider tpm2 -provider base -in testkey.priv -text -noout
```

Note: if the private key usage requires authorization you will be asked for a
password although exporting a public key does not require it. You may set
an empty password or anything else.


## Loading a Private Key

The tpm2 provider implements three
[OSSL_OP_STORE](https://www.openssl.org/docs/manmaster/man7/provider-storemgmt.html)
loaders:
 * **file** (default), to load the PEM file (`TSS2 PRIVATE KEY`);
 * **handle**, to load persistent keys, or data (public keys or certificates)
   from NV indices;
 * **object**, to load serialized object representing a persistent handle.

These are used by the
[OSSL_STORE](https://www.openssl.org/docs/manmaster/man7/ossl_store.html)
API functions and all `openssl` commands that require a private key.

Note the tpm2 provider does not implement public key operations. Use the default
openssl provider for these.
For example, to print out the value of the modulus of the public key simply do:
```
openssl rsa -modulus -noout -in testkey.pub
```

### Using PEM File

To load a TPM-based private key, simply specify a name of a PEM file
(`TSS2 PRIVATE KEY`), possibly with the optional `file:` prefix and a full path.
For example, to print out the value of the modulus of the private key:
```
openssl rsa -provider tpm2 -provider base -modulus -noout -in file:/etc/ssl/testkey.priv
```

The password may be supplied using the standard OpenSSL mechanism. You can use
the `-passin`
[option](https://www.openssl.org/docs/manmaster/man1/openssl-passphrase-options.html),
or (since the file contains an indicator whether an authorization is required)
an interactive password prompt appears.
For example, to use the password `abc`:
```
openssl rsa -provider tpm2 -provider base -modulus -noout -in testkey.priv -passin pass:abc
```

### Using Key Handle

To load a persistent key using its handle, specify the prefix `handle:` and
then a hexadecimal number, e.g. `handle:0x81000000`. This works with any OpenSSL
operation.

For example, to print out the value of the modulus of the persistent key:
```
openssl rsa -provider tpm2 -modulus -noout -in handle:0x81000000
```

An authorization may be required to use the key. To supply a password you need
first to append `?pass` to the URI, e.g. `handle:0x81000000?pass`.
This activates the `pem_password_cb` callback.

To supply a password via the command-line tool, use then the standard
[`-passin` option](https://www.openssl.org/docs/manmaster/man1/openssl-passphrase-options.html).
All argument types (`pass:`, `env:`, `file:`, `fd:`, `stdin`) may be used.
For example, to supply a password from an evironment variable $PASSWORD:
```
openssl rsa -provider tpm2 -modulus -noout -in handle:0x81000000?pass -passin env:PASSWORD
```

### Using NV Index

Public keys or certificates may be stored in the NV Index. To load data from
NV Index, specify the prefix `handle:` and then a hexadecimal number, e.g.
`handle:0x1000010`.

For example, to derive a shared secret from a persistent private key and a peer
key that is stored in an NV Index:
```
openssl pkeyutl -provider tpm2 -provider base -derive -inkey handle:0x81000000 -peerkey handle:0x1000010 -out secret.key
```

### Using a Serialized Object

The `tpm2_evictcontrol` command can optionally output a serialized object
representing the persistent handle:
```
tpm2_evictcontrol -c ak_rsa.ctx -o ak_rsa.obj
```

To load a persistent key using the serialized object, specify the prefix
`object:` and then a file name:
```
openssl rsa -provider tpm2 -modulus -noout -in object:ak_rsa.obj
```