]>
Commit | Line | Data |
---|---|---|
e33b132a RL |
1 | =pod |
2 | ||
3 | =head1 NAME | |
4 | ||
5 | EVP_PKEY - an internal description | |
6 | ||
7 | =head1 SYNOPSIS | |
8 | ||
9 | #include "crypto/evp.h" | |
10 | ||
1695e10e | 11 | typedef struct evp_pkey_st EVP_PKEY; |
e33b132a RL |
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 | |
1695e10e | 18 | private/public key pairs, but has had other uses as well. |
e33b132a RL |
19 | |
20 | =for comment "uses" could as well be "abuses"... | |
21 | ||
e304aa87 | 22 | The private/public key pair that an B<EVP_PKEY> contains is referred to |
1695e10e RL |
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 | |
cc57dc96 MC |
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. | |
1695e10e RL |
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(). | |
e33b132a RL |
135 | |
136 | If such caching isn't supported, the operations that can be performed | |
1695e10e RL |
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 | |
e33b132a RL |
139 | keys). |
140 | ||
1695e10e RL |
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 | ||
b574c6a9 MC |
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 | |
cc57dc96 MC |
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. | |
1695e10e | 198 | |
e33b132a RL |
199 | =head1 SEE ALSO |
200 | ||
201 | L<provider-keymgmt(7)> | |
202 | ||
203 | =head1 COPYRIGHT | |
204 | ||
fecb3aae | 205 | Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved. |
e33b132a RL |
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 |