]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
docs: update man3 and man7 with cipher pipeline APIs 26136/head
authorRamkumar <therealramkumar@gmail.com>
Sun, 10 Nov 2024 17:50:04 +0000 (23:20 +0530)
committerMatt Caswell <matt@openssl.org>
Tue, 17 Dec 2024 11:59:32 +0000 (11:59 +0000)
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/24636)

CHANGES.md
doc/man3/EVP_EncryptInit.pod
doc/man7/provider-cipher.pod
include/openssl/evp.h

index 1e3a5b53ad88e3a0103c13706ee4b979cbba16b8..d3e5f18ffda303f900b9c729302ce2c7f3bed7c2 100644 (file)
@@ -84,6 +84,17 @@ OpenSSL 3.5
 
    *Dan Zimmerman, Alina Elizarova*
 
+ * Cipher pipelining support for provided ciphers with new API functions
+   EVP_CIPHER_can_pipeline(), EVP_CipherPipelineEncryptInit(),
+   EVP_CipherPipelineDecryptInit(), EVP_CipherPipelineUpdate(),
+   and EVP_CipherPipelineFinal(). Cipher pipelining support allows application to
+   submit multiple chunks of data in one cipher update call, thereby allowing the
+   provided implementation to take advantage of parallel computing. There are
+   currently no built-in ciphers that support pipelining. This new API replaces
+   the legacy pipeline API [SSL_CTX_set_max_pipelines](https://docs.openssl.org/3.3/man3/SSL_CTX_set_split_send_fragment/) used with Engines.
+
+   *Ramkumar*
+
 OpenSSL 3.4
 -----------
 
index f1e4db92fdf4617275124029d5e56e39a7cd0043..f388a0a9c3db4c8704ff5af8d58fb4951d9960aa 100644 (file)
@@ -31,6 +31,11 @@ EVP_DecryptFinal,
 EVP_CipherInit,
 EVP_CipherFinal,
 EVP_Cipher,
+EVP_CIPHER_can_pipeline,
+EVP_CipherPipelineEncryptInit,
+EVP_CipherPipelineDecryptInit,
+EVP_CipherPipelineUpdate,
+EVP_CipherPipelineFinal,
 EVP_get_cipherbyname,
 EVP_get_cipherbynid,
 EVP_get_cipherbyobj,
@@ -156,6 +161,25 @@ EVP_CIPHER_CTX_mode
  int EVP_Cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
                 const unsigned char *in, unsigned int inl);
 
+ int EVP_CIPHER_can_pipeline(const EVP_CIPHER *cipher, int enc);
+ int EVP_CipherPipelineEncryptInit(EVP_CIPHER_CTX *ctx,
+                                   const EVP_CIPHER *cipher,
+                                   const unsigned char *key, size_t keylen,
+                                   size_t numpipes,
+                                   const unsigned char **iv, size_t ivlen);
+ int EVP_CipherPipelineDecryptInit(EVP_CIPHER_CTX *ctx,
+                                   const EVP_CIPHER *cipher,
+                                   const unsigned char *key, size_t keylen,
+                                   size_t numpipes,
+                                   const unsigned char **iv, size_t ivlen);
+ int EVP_CipherPipelineUpdate(EVP_CIPHER_CTX *ctx,
+                              unsigned char **out, size_t *outl,
+                              const size_t *outsize,
+                              const unsigned char **in, const size_t *inl);
+ int EVP_CipherPipelineFinal(EVP_CIPHER_CTX *ctx,
+                             unsigned char **outm, size_t *outl,
+                             const size_t *outsize);
+
  int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *x, int padding);
  int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *x, int keylen);
  int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int cmd, int p1, void *p2);
@@ -462,6 +486,51 @@ Due to the constraints of the API contract of this function it shouldn't be used
 in applications, please consider using EVP_CipherUpdate() and
 EVP_CipherFinal_ex() instead.
 
+=item EVP_CIPHER_can_pipeline()
+
+This function checks if a B<EVP_CIPHER> fetched using EVP_CIPHER_fetch() supports
+cipher pipelining. If the cipher supports pipelining, it returns 1, otherwise 0.
+This function will return 0 for non-fetched ciphers such as EVP_aes_128_gcm().
+There are currently no built-in ciphers that support pipelining.
+
+Cipher pipelining support allows an application to submit multiple chunks of
+data in one set of EVP_CipherUpdate()/EVP_CipherFinal calls, thereby allowing
+the provided implementation to take advantage of parallel computing. This is
+beneficial for hardware accelerators as pipeline amortizes the latency over
+multiple chunks.
+
+For non-fetched ciphers, EVP_CipherPipelineEncryptInit() or
+EVP_CipherPipelineDecryptInit() may be directly called, which will perform a
+fetch and return an error if a pipeline supported implementation is not found.
+
+=item EVP_CipherPipelineEncryptInit(), EVP_CipherPipelineDecryptInit(), EVP_CipherPipelineUpdate() and EVP_CipherPipelineFinal()
+
+These functions can be used to perform multiple encryption or decryption
+operations in parallel. EVP_CIPHER_can_pipeline() may be called to check if the
+cipher supports pipelining. These functions are analogous to
+EVP_EncryptInit_ex2(), EVP_DecryptInit_ex2(), EVP_CipherUpdate() and
+EVP_CipherFinal() but take an array of pointers for iv, input and output buffers.
+
+The I<key>, of length I<keylen>, is the symmetric key to use. The I<numpipes>
+parameter specifies the number of parallel operations to perform. The
+I<numpipes> cannot exceed B<EVP_MAX_PIPES>. The I<iv> parameter is an array of
+buffer pointers, containing IVs. The array size must be equal to I<numpipes>.
+The size of each IV buffer must be equal to I<ivlen>. When IV is not provided,
+I<iv> must be NULL, rather than an array of NULL pointers. The I<in>
+parameters takes an array of buffer pointers, each pointing to a buffer
+containing the input data. The buffers can be of different sizes. The I<inl>
+parameter is an array of size_t, each specifying the size of the corresponding
+input buffer. The I<out> and I<outm> parameters are arrays of buffer pointers,
+each pointing to a buffer where the output data will be written. The I<outsize>
+parameter is an array of size_t, each specifying the size of the corresponding
+output buffer. The I<outl> parameter is an array of size_t which will be updated
+with the size of the output data written to the corresponding output buffer.
+For size requirement of the output buffers, see the description of EVP_CipherUpdate().
+
+The EVP_CipherPipelineUpdate() function can be called multiple times to encrypt
+successive blocks of data. For AAD data, the I<out>, and I<outsize> parameter
+should be NULL, rather than an array of NULL pointers.
+
 =item EVP_get_cipherbyname(), EVP_get_cipherbynid() and EVP_get_cipherbyobj()
 
 Returns an B<EVP_CIPHER> structure when passed a cipher name, a cipher B<NID> or
@@ -773,6 +842,13 @@ See also EVP_CIPHER_CTX_get_key_length() and EVP_CIPHER_CTX_set_key_length().
 Gets or sets the AEAD tag for the associated cipher context I<ctx>.
 See L<EVP_EncryptInit(3)/AEAD Interface>.
 
+=item "pipeline-tag" (B<OSSL_CIPHER_PARAM_PIPELINE_AEAD_TAG>) <octet ptr>
+
+Gets or sets the AEAD tag when using cipher pipelining. The pointer must 
+point to an array of buffers, where the aead tag will be read from or written to.
+The array size must be equal to I<numpipes> used in
+EVP_CipherPipelineEncryptInit() or EVP_CipherPipelineDecryptInit().
+
 =item "keybits" (B<OSSL_CIPHER_PARAM_RC2_KEYBITS>) <unsigned integer>
 
 Gets or sets the effective keybits used for a RC2 cipher.
@@ -1317,6 +1393,14 @@ encryption/decryption, or the number of bytes authenticated in a call specifying
 AAD for an AEAD cipher, if the flag B<EVP_CIPH_FLAG_CUSTOM_CIPHER> is set for
 the cipher.
 
+EVP_CIPHER_can_pipeline() returns 1 if the cipher can be used in a pipeline, 0 otherwise.
+
+EVP_CipherPipelineEncryptInit() and EVP_CipherPipelineDecryptInit()
+return 1 for success and 0 for failure.
+
+EVP_CipherPipelineUpdate() and EVP_CipherPipelineFinal()
+return 1 for success and 0 for failure.
+
 EVP_CIPHER_CTX_reset() returns 1 for success and 0 for failure.
 
 EVP_get_cipherbyname(), EVP_get_cipherbynid() and EVP_get_cipherbyobj()
index eaad3cf2ff021abeee1c7f44e7e0ec760d59e206..8f23aae0daa110e5280930f305cb253f7bbac783 100644 (file)
@@ -36,6 +36,23 @@ provider-cipher - The cipher library E<lt>-E<gt> provider functions
  int OSSL_FUNC_cipher_cipher(void *cctx, unsigned char *out, size_t *outl,
                              size_t outsize, const unsigned char *in, size_t inl);
 
+ /* Encryption/decryption using cipher pipeline */
+ int OSSL_FUNC_cipher_pipeline_encrypt_init(void *cctx, const unsigned char *key,
+                                            size_t keylen, size_t numpipes,
+                                            const unsigned char **iv, size_t ivlen,
+                                            const OSSL_PARAM params[]))
+ int OSSL_FUNC_cipher_pipeline_decrypt_init(void *cctx, const unsigned char *key,
+                                            size_t keylen, size_t numpipes,
+                                            const unsigned char **iv, size_t ivlen,
+                                            const OSSL_PARAM params[]))
+ int OSSL_FUNC_cipher_pipeline_update(void *cctx, size_t numpipes,
+                                      unsigned char **out, size_t *outl,
+                                      const size_t *outsize,
+                                      const unsigned char **in, const size_t *inl))
+ int OSSL_FUNC_cipher_pipeline_final(void *cctx, size_t numpipes,
+                                     unsigned char **out, size_t *outl,
+                                     const size_t *outsize))
+
  /* Cipher parameter descriptors */
  const OSSL_PARAM *OSSL_FUNC_cipher_gettable_params(void *provctx);
 
@@ -81,28 +98,34 @@ For example, the "function" OSSL_FUNC_cipher_newctx() has these:
 L<OSSL_DISPATCH(3)> arrays are indexed by numbers that are provided as
 macros in L<openssl-core_dispatch.h(7)>, as follows:
 
- OSSL_FUNC_cipher_newctx               OSSL_FUNC_CIPHER_NEWCTX
- OSSL_FUNC_cipher_freectx              OSSL_FUNC_CIPHER_FREECTX
- OSSL_FUNC_cipher_dupctx               OSSL_FUNC_CIPHER_DUPCTX
+ OSSL_FUNC_cipher_newctx                    OSSL_FUNC_CIPHER_NEWCTX
+ OSSL_FUNC_cipher_freectx                   OSSL_FUNC_CIPHER_FREECTX
+ OSSL_FUNC_cipher_dupctx                    OSSL_FUNC_CIPHER_DUPCTX
+
+ OSSL_FUNC_cipher_encrypt_init              OSSL_FUNC_CIPHER_ENCRYPT_INIT
+ OSSL_FUNC_cipher_decrypt_init              OSSL_FUNC_CIPHER_DECRYPT_INIT
+ OSSL_FUNC_cipher_update                    OSSL_FUNC_CIPHER_UPDATE
+ OSSL_FUNC_cipher_final                     OSSL_FUNC_CIPHER_FINAL
+ OSSL_FUNC_cipher_cipher                    OSSL_FUNC_CIPHER_CIPHER
 
- OSSL_FUNC_cipher_encrypt_init         OSSL_FUNC_CIPHER_ENCRYPT_INIT
- OSSL_FUNC_cipher_decrypt_init         OSSL_FUNC_CIPHER_DECRYPT_INIT
- OSSL_FUNC_cipher_update               OSSL_FUNC_CIPHER_UPDATE
- OSSL_FUNC_cipher_final                OSSL_FUNC_CIPHER_FINAL
- OSSL_FUNC_cipher_cipher               OSSL_FUNC_CIPHER_CIPHER
+ OSSL_FUNC_cipher_pipeline_encrypt_init     OSSL_FUNC_CIPHER_PIPELINE_ENCRYPT_INIT
+ OSSL_FUNC_cipher_pipeline_decrypt_init     OSSL_FUNC_CIPHER_PIPELINE_DECRYPT_INIT
+ OSSL_FUNC_cipher_pipeline_update           OSSL_FUNC_CIPHER_PIPELINE_UPDATE
+ OSSL_FUNC_cipher_pipeline_final            OSSL_FUNC_CIPHER_PIPELINE_FINAL
 
- OSSL_FUNC_cipher_get_params           OSSL_FUNC_CIPHER_GET_PARAMS
- OSSL_FUNC_cipher_get_ctx_params       OSSL_FUNC_CIPHER_GET_CTX_PARAMS
- OSSL_FUNC_cipher_set_ctx_params       OSSL_FUNC_CIPHER_SET_CTX_PARAMS
+ OSSL_FUNC_cipher_get_params                OSSL_FUNC_CIPHER_GET_PARAMS
+ OSSL_FUNC_cipher_get_ctx_params            OSSL_FUNC_CIPHER_GET_CTX_PARAMS
+ OSSL_FUNC_cipher_set_ctx_params            OSSL_FUNC_CIPHER_SET_CTX_PARAMS
 
- OSSL_FUNC_cipher_gettable_params      OSSL_FUNC_CIPHER_GETTABLE_PARAMS
- OSSL_FUNC_cipher_gettable_ctx_params  OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS
- OSSL_FUNC_cipher_settable_ctx_params  OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS
+ OSSL_FUNC_cipher_gettable_params           OSSL_FUNC_CIPHER_GETTABLE_PARAMS
+ OSSL_FUNC_cipher_gettable_ctx_params       OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS
+ OSSL_FUNC_cipher_settable_ctx_params       OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS
 
 A cipher algorithm implementation may not implement all of these functions.
 In order to be a consistent set of functions there must at least be a complete
 set of "encrypt" functions, or a complete set of "decrypt" functions, or a
-single "cipher" function.
+single "cipher" function. Similarly, there can be a complete set of pipeline
+"encrypt" functions, and/or a complete set of pipeline "decrypt" functions.
 In all cases both the OSSL_FUNC_cipher_newctx and OSSL_FUNC_cipher_freectx functions must be
 present.
 All other functions are optional.
@@ -179,6 +202,16 @@ The output from the encryption/decryption should be stored in I<out> and the
 amount of data stored should be put in I<*outl> which should be no more than
 I<outsize> bytes.
 
+OSSL_FUNC_cipher_pipeline_encrypt_init(), OSSL_FUNC_cipher_pipeline_decrypt_init()
+OSSL_FUNC_cipher_pipeline_update(), and OSSL_FUNC_cipher_pipeline_final() are similar to
+the non-pipeline variants, but are used when the application is using cipher pipelining.
+The I<numpipes> parameter is the number of pipes in the pipeline. The I<iv> parameter
+is an array of buffers with IVs, each I<ivlen> bytes long. The I<in> and I<out> are
+arrays of buffer pointers. The I<inl> and I<outl>, I<outsize> are arrays of size_t
+representing corresponding buffer length as similar to the non-pipeline variants.
+All arrays are of length I<numpipes>. See L<EVP_CipherPipelineEncryptInit(3)> for more
+information.
+
 =head2 Cipher Parameters
 
 See L<OSSL_PARAM(3)> for further details on the parameters structure used by
@@ -216,8 +249,11 @@ OSSL_FUNC_cipher_newctx() and OSSL_FUNC_cipher_dupctx() should return the newly
 provider side cipher context, or NULL on failure.
 
 OSSL_FUNC_cipher_encrypt_init(), OSSL_FUNC_cipher_decrypt_init(), OSSL_FUNC_cipher_update(),
-OSSL_FUNC_cipher_final(), OSSL_FUNC_cipher_cipher(), OSSL_FUNC_cipher_get_params(),
-OSSL_FUNC_cipher_get_ctx_params() and OSSL_FUNC_cipher_set_ctx_params() should return 1 for
+OSSL_FUNC_cipher_final(), OSSL_FUNC_cipher_cipher(),
+OSSL_FUNC_cipher_pipeline_encrypt_init(), OSSL_FUNC_cipher_pipeline_decrypt_init(),
+OSSL_FUNC_cipher_pipeline_update(), OSSL_FUNC_cipher_pipeline_final(),
+OSSL_FUNC_cipher_get_params(), OSSL_FUNC_cipher_get_ctx_params() and
+OSSL_FUNC_cipher_set_ctx_params() should return 1 for
 success or 0 on error.
 
 OSSL_FUNC_cipher_gettable_params(), OSSL_FUNC_cipher_gettable_ctx_params() and
index 23c4095596d3ee573329c374359f074d5c33e96b..01caaadcde0527ba05a4e3ba4940c46b0c1e67c0 100644 (file)
@@ -37,6 +37,7 @@
 # define EVP_MAX_BLOCK_LENGTH            32
 # define EVP_MAX_AEAD_TAG_LENGTH         16
 
+/* Maximum pipes in cipher pipelining */
 # define EVP_MAX_PIPES                   32
 
 # define PKCS5_SALT_LEN                  8