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