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