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