2
0

EVP_PKEY.pod 7.8 KB

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