1 | =pod
|
---|
2 |
|
---|
3 | =head1 NAME
|
---|
4 |
|
---|
5 | EVP_PKEY - an internal description
|
---|
6 |
|
---|
7 | =head1 SYNOPSIS
|
---|
8 |
|
---|
9 | #include "crypto/evp.h"
|
---|
10 |
|
---|
11 | typedef struct evp_pkey_st EVP_PKEY;
|
---|
12 |
|
---|
13 | =head1 DESCRIPTION
|
---|
14 |
|
---|
15 | I<This is not a complete description yet>
|
---|
16 |
|
---|
17 | B<EVP_PKEY> is a complex type that's essentially a container for
|
---|
18 | private/public key pairs, but has had other uses as well.
|
---|
19 |
|
---|
20 | =for comment "uses" could as well be "abuses"...
|
---|
21 |
|
---|
22 | The private/public key pair that an B<EVP_PKEY> contains is refered to
|
---|
23 | as its "internal key" or "origin" (the reason for "origin" is
|
---|
24 | explained further down, in L</Export cache for provider operations>),
|
---|
25 | and it can take one of the following forms:
|
---|
26 |
|
---|
27 | =over 4
|
---|
28 |
|
---|
29 | =item legacy origin
|
---|
30 |
|
---|
31 | This is the form that an B<EVP_PKEY> in OpenSSL prior to 3.0 had. The
|
---|
32 | internal key in the B<EVP_PKEY> is a pointer to the low-level key
|
---|
33 | types, such as B<RSA>, B<DSA> and B<EC>, or an engine driven
|
---|
34 | structure, and is governed by an associated L<EVP_PKEY_METHOD(3)> and
|
---|
35 | an L<EVP_PKEY_ASN1_METHOD(3)>.
|
---|
36 |
|
---|
37 | The functions available through those two method structures get full
|
---|
38 | access to the B<EVP_PKEY> and therefore have a lot of freedom to
|
---|
39 | modify whatever they want. This also means that an B<EVP_PKEY> is a
|
---|
40 | shared structure between libcrypto and any ENGINE that serves such
|
---|
41 | methods.
|
---|
42 |
|
---|
43 | =item provider-native origin
|
---|
44 |
|
---|
45 | This is a new form in OpenSSL 3.0, which permits providers to hold the
|
---|
46 | key data (see L<provider-keymgmt(7)>). The internal key in the
|
---|
47 | B<EVP_PKEY> is a pointer to that key data held by the provider, and
|
---|
48 | is governed by an associated L<EVP_KEYMGMT(3)> method structure.
|
---|
49 |
|
---|
50 | The functions available through the L<EVP_KEYMGMT(3)> have no access
|
---|
51 | to the B<EVP_PKEY>, and can therefore not make any direct changes.
|
---|
52 | Similarly, the key data that the B<EVP_PKEY> points at is only known
|
---|
53 | to the functions pointed at in the L<EVP_KEYMGMT(3)>.
|
---|
54 |
|
---|
55 | =back
|
---|
56 |
|
---|
57 | These two forms can never co-exist in the same B<EVP_PKEY>, the main
|
---|
58 | reason being that having both at the same time will create problems
|
---|
59 | with synchronising between the two forms, and potentially make it
|
---|
60 | confusing which one of the two is the origin.
|
---|
61 |
|
---|
62 | =head2 Key mutability
|
---|
63 |
|
---|
64 | The B<EVP_PKEY> internal keys are mutable.
|
---|
65 |
|
---|
66 | This is especially visible with internal legacy keys, since they can
|
---|
67 | be extracted with functions like L<EVP_PKEY_get0_RSA(3)> and then
|
---|
68 | modified at will with functions like L<RSA_set0_key(3)>. Note that if the
|
---|
69 | internal key is a provider key then the return value from functions such as
|
---|
70 | L<EVP_PKEY_get0_RSA(3)> is a cached copy of the key. Changes to the cached
|
---|
71 | copy are not reflected back in the provider key.
|
---|
72 |
|
---|
73 | Internal provider native keys are also possible to be modified, if the
|
---|
74 | associated L<EVP_KEYMGMT(3)> implementation allows it. This is done
|
---|
75 | with L<EVP_PKEY_set_params(3)> and its specialised derivatives. The
|
---|
76 | OpenSSL providers allow it for the following:
|
---|
77 |
|
---|
78 | =over 4
|
---|
79 |
|
---|
80 | =item DH, EC, X25519, X448:
|
---|
81 |
|
---|
82 | It's possible to set the encoded public key. This is supported in
|
---|
83 | particular through L<EVP_PKEY_set1_encoded_public_key(3)>.
|
---|
84 |
|
---|
85 | =item EC:
|
---|
86 |
|
---|
87 | It's possible to flip the ECDH cofactor mode.
|
---|
88 |
|
---|
89 | =back
|
---|
90 |
|
---|
91 | Every time the B<EVP_PKEY> internal key mutates, an internal dirty
|
---|
92 | count is incremented. The need for a dirty count is explained further
|
---|
93 | in L</Export cache for provider operations>.
|
---|
94 |
|
---|
95 | For provider native origin keys, this doesn't require any help from
|
---|
96 | the L<EVP_KEYMGMT(3)>, the dirty count is maintained in the B<EVP_PKEY>
|
---|
97 | itself, and is incremented every time L<EVP_PKEY_set_params(3)> or its
|
---|
98 | specialised derivatives are called.
|
---|
99 | For legacy origin keys, this requires the associated
|
---|
100 | L<EVP_PKEY_ASN1_METHOD(3)> to implement the dirty_cnt() function. All
|
---|
101 | of OpenSSL's built-in L<EVP_PKEY_ASN1_METHOD(3)> implement this
|
---|
102 | function.
|
---|
103 |
|
---|
104 | =head2 Export cache for provider operations
|
---|
105 |
|
---|
106 | OpenSSL 3.0 can handle operations such as signing, encrypting, etc in
|
---|
107 | diverse providers, potentially others than the provider of the
|
---|
108 | L<EVP_KEYMGMT(3)>. Two providers, possibly from different vendors,
|
---|
109 | can't be expected to share internal key structures. There are
|
---|
110 | therefore instances where key data will need to be exported to the
|
---|
111 | provider that is going to perform the operation (this also implies
|
---|
112 | that every provider that implements a key pair based operation must
|
---|
113 | also implement an L<EVP_KEYMGMT(3)>).
|
---|
114 |
|
---|
115 | For performance reasons, libcrypto tries to minimize the need to
|
---|
116 | perform such an export, so it maintains a cache of such exports in the
|
---|
117 | B<EVP_PKEY>. Each cache entry has two items, a pointer to the
|
---|
118 | provider side key data and the associated L<EVP_KEYMGMT(3)>.
|
---|
119 |
|
---|
120 | I<This cache is often referred to as the "operation key cache", and
|
---|
121 | the key data that the cached keys came from is the "origin", and since
|
---|
122 | there are two forms of the latter, we have the "legacy origin" and the
|
---|
123 | "provider native origin".>
|
---|
124 |
|
---|
125 | The export to the operation key cache can be performed independent of
|
---|
126 | what form the origin has.
|
---|
127 | For a legacy origin, this requires that the associated
|
---|
128 | L<EVP_PKEY_ASN1_METHOD(3)> implements the functions export_to() and
|
---|
129 | dirty_cnt().
|
---|
130 | For a provider native origin, this requires that the associated
|
---|
131 | L<EVP_KEYMGMT(3)> implements the OSSL_FUNC_keymgmt_export() function
|
---|
132 | (see L<provider-keymgmt(7)>).
|
---|
133 | In all cases, the receiving L<EVP_KEYMGMT(3)> (the one associated with
|
---|
134 | the exported key data) must implement OSSL_FUNC_keymgmt_import().
|
---|
135 |
|
---|
136 | If such caching isn't supported, the operations that can be performed
|
---|
137 | with that key are limited to the same backend as the origin key
|
---|
138 | (ENGINE for legacy origin keys, provider for provider side origin
|
---|
139 | keys).
|
---|
140 |
|
---|
141 | =head3 Exporting implementation details
|
---|
142 |
|
---|
143 |
|
---|
144 | Exporting a key to the operation cache involves the following:
|
---|
145 |
|
---|
146 | =over 4
|
---|
147 |
|
---|
148 | =item 1.
|
---|
149 |
|
---|
150 | Check if the dirty count for the internal origin key has changed since
|
---|
151 | the previous time. This is done by comparing it with a copy of the
|
---|
152 | dirty count, which is maintained by the export function.
|
---|
153 |
|
---|
154 | If the dirty count has changed, the export cache is cleared.
|
---|
155 |
|
---|
156 | =item 2.
|
---|
157 |
|
---|
158 | Check if there's an entry in the export cache with the same
|
---|
159 | L<EVP_KEYMGMT(3)> that's the same provider that an export is to be
|
---|
160 | made to (which is the provider that's going to perform an operation
|
---|
161 | for which the current B<EVP_PKEY> is going to be used).
|
---|
162 |
|
---|
163 | If such an entry is found, nothing more is done, the key data and
|
---|
164 | L<EVP_KEYMGMT(3)> found in that export cache entry will be used for
|
---|
165 | the operation to be performed.
|
---|
166 |
|
---|
167 | =item 3.
|
---|
168 |
|
---|
169 | Export the internal origin key to the provider, using the appropriate
|
---|
170 | method.
|
---|
171 |
|
---|
172 | For legacy origin keys, that's done with the help of the
|
---|
173 | L<EVP_PKEY_ASN1_METHOD(3)> export_to() function.
|
---|
174 |
|
---|
175 | For provider native origin keys, that's done by retrieving the key
|
---|
176 | data in L<OSSL_PARAM(3)> form from the origin keys, using the
|
---|
177 | OSSL_FUNC_keymgmt_export() functions of the associated
|
---|
178 | L<EVP_KEYMGMT(3)>, and sending that data to the L<EVP_KEYMGMT(3)> of
|
---|
179 | the provider that's to perform the operation, using its
|
---|
180 | OSSL_FUNC_keymgmt_import() function.
|
---|
181 |
|
---|
182 | =back
|
---|
183 |
|
---|
184 | =head2 Changing a key origin
|
---|
185 |
|
---|
186 | It is never possible to change the origin of a key. An B<EVP_PKEY> with a legacy
|
---|
187 | origin will I<never> be upgraded to become an B<EVP_PKEY> with a provider
|
---|
188 | native origin. Instead, we have the operation cache as described above, that
|
---|
189 | takes care of the needs of the diverse operation the application may want to
|
---|
190 | perform.
|
---|
191 |
|
---|
192 | Similarly an B<EVP_PKEY> with a provider native origin, will I<never> be
|
---|
193 | I<transformed> into an B<EVP_PKEY> with a legacy origin. Instead we may have a
|
---|
194 | cached copy of the provider key in legacy form. Once the cached copy is created
|
---|
195 | it is never updated. Changes made to the provider key are not reflected back in
|
---|
196 | the cached legacy copy. Similarly changes made to the cached legacy copy are not
|
---|
197 | reflected back in the provider key.
|
---|
198 |
|
---|
199 | =head1 SEE ALSO
|
---|
200 |
|
---|
201 | L<provider-keymgmt(7)>
|
---|
202 |
|
---|
203 | =head1 COPYRIGHT
|
---|
204 |
|
---|
205 | Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved.
|
---|
206 |
|
---|
207 | Licensed under the Apache License 2.0 (the "License"). You may not use
|
---|
208 | this file except in compliance with the License. You can obtain a copy
|
---|
209 | in the file LICENSE in the source distribution or at
|
---|
210 | L<https://www.openssl.org/source/license.html>.
|
---|
211 |
|
---|
212 | =cut
|
---|