Skip to content

Commit

Permalink
docs: update man3 and man7 with cipher pipeline APIs
Browse files Browse the repository at this point in the history
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from openssl#24636)
  • Loading branch information
ramenhost authored and mattcaswell committed Dec 17, 2024
1 parent a055154 commit c44066b
Show file tree
Hide file tree
Showing 4 changed files with 149 additions and 17 deletions.
11 changes: 11 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
-----------

Expand Down
84 changes: 84 additions & 0 deletions doc/man3/EVP_EncryptInit.pod
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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()
Expand Down
70 changes: 53 additions & 17 deletions doc/man7/provider-cipher.pod
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions include/openssl/evp.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit c44066b

Please sign in to comment.