doc: improve documentation of EVP in-place encryption

The EVP interface explicitly allows in-place encryption/decryption,
but this fact is just 'partially' documented in `EVP_EncryptUpdate(3)`
(pun intended): the manual page mentions only operation failure in
case of 'partial' overlaps. This is not even correct, because
the check for partially overlapping buffers is only implemented
in legacy code paths.

Currently, in-place encryption/decryption is only documented for
RSA (`RSA_public_encrypt(3)`) and DES (`DES_ecb_encrypt(3)`), as
well as in the provider interface (`provider-cipher(7)`).

This commit amends `EVP_EncryptUpdate(3)` and `provider-cipher(7)`
to make the front-end and back-end documentation consistent.

Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Tom Cosgrove <tom.cosgrove@arm.com>
(Merged from https://github.com/openssl/openssl/pull/22875)
This commit is contained in:
Matthias St. Pierre 2023-11-29 22:12:45 +01:00
parent 986c48c4eb
commit 6ebdbba76a
2 changed files with 16 additions and 8 deletions

View File

@ -373,7 +373,12 @@ exists.
=item EVP_EncryptUpdate()
Encrypts I<inl> bytes from the buffer I<in> and writes the encrypted version to
I<out>. This function can be called multiple times to encrypt successive blocks
I<out>. The pointers I<out> and I<in> may point to the same location, in which
case the encryption will be done in-place. If I<out> and I<in> point to different
locations, the two buffers must be disjoint, otherwise the operation might fail
or the outcome might be undefined.
This function can be called multiple times to encrypt successive blocks
of data. The amount of data written depends on the block alignment of the
encrypted data.
For most ciphers and modes, the amount of data written can be anything
@ -382,10 +387,9 @@ For wrap cipher modes, the amount of data written can be anything
from zero bytes to (inl + cipher_block_size) bytes.
For stream ciphers, the amount of data written can be anything from zero
bytes to inl bytes.
Thus, I<out> should contain sufficient room for the operation being performed.
The actual number of bytes written is placed in I<outl>. It also
checks if I<in> and I<out> are partially overlapping, and if they are
0 is returned to indicate failure.
Thus, the buffer pointed to by I<out> must contain sufficient room for the
operation being performed.
The actual number of bytes written is placed in I<outl>.
If padding is enabled (the default) then EVP_EncryptFinal_ex() encrypts
the "final" data, that is any data that remains in a partial block.

View File

@ -148,9 +148,13 @@ It is the responsibility of the cipher implementation to handle input lengths
that are not multiples of the block length.
In such cases a cipher implementation will typically cache partial blocks of
input data until a complete block is obtained.
I<out> may be the same location as I<in> but it should not partially overlap.
The same expectations apply to I<outsize> as documented for
L<EVP_EncryptUpdate(3)> and L<EVP_DecryptUpdate(3)>.
The pointers I<out> and I<in> may point to the same location, in which
case the encryption must be done in-place. If I<out> and I<in> point to different
locations, the requirements of L<EVP_EncryptUpdate(3)> and L<EVP_DecryptUpdate(3)>
guarantee that the two buffers are disjoint.
Similarly, the requirements of L<EVP_EncryptUpdate(3)> and L<EVP_DecryptUpdate(3)>
ensure that the buffer pointed to by I<out> contains sufficient room for the
operation being performed.
OSSL_FUNC_cipher_final() completes an encryption or decryption started through previous
OSSL_FUNC_cipher_encrypt_init() or OSSL_FUNC_cipher_decrypt_init(), and OSSL_FUNC_cipher_update()