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