Output buffer length in EVP_EncryptUpdate for ECB mode
Matt Caswell
matt at openssl.org
Thu Nov 3 14:57:45 UTC 2022
On 03/11/2022 14:21, Wiktor Kwapisiewicz via openssl-users wrote:
> Hello,
>
> I'd like to clarify one aspect of the API regarding EVP_EncryptUpdate
> [0] that is the length of the output buffer that should be passed to
> that function ("out" parameter). (Actually I'm using EVP_CipherUpdate
> but the docs are more comprehensive for EVP_EncryptUpdate).
>
> [0]: https://www.openssl.org/docs/manmaster/man3/EVP_EncryptUpdate.html
>
> For the record I'm using AES-128 cipher in ECB mode and the docs say:
>
>> For most ciphers and modes, the amount of data written can be
>> anything from zero bytes to (inl + cipher_block_size - 1) bytes. 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.
>
> AES-128-ECB doesn't appear to be a stream cipher (since the "block size"
> returns 16 not the magical value of 1) and I'm unable to find any
> mentions of "wrap cipher modes" in search engines. Apparently ECB is a
> block cipher mode.
>
> Does that mean that "wrap cipher modes" == "block cipher modes"?
No.
The term "block cipher" is a feature of the underlying primitive - so
AES-128 is a block cipher. It encrypts in blocks of 16 bytes. ECB is a
particular mode for using a block cipher. "Wrap" modes are specialist
modes used for encrypting key material.
>
> Is there any documentation I could read on the reasoning of why a space
> for additional block is needed in this case ("(inl + cipher_block_size)
> bytes")? I'm trying to understand the differences between OpenSSL and
> other cryptographic backends in an OpenPGP library [1].
EVP_EncryptUpdate() can be called repeatedly, incrementally feeding in
the data to be encrypted. The ECB mode (when used with AES-128) will
encrypt input data 16 bytes at a time, and the output size will also be
16 bytes per input block. If the data that you feed in to
EVP_EncryptUpdate() is not a multiple of 16 bytes then the amount of
data that is over a multiple of 16 bytes will be cached until a
subsequent call where it does have 16 bytes.
Let's say you call EVP_EncryptUpdate() with 15 bytes of data. In that
case all 15 bytes will be cached and 0 bytes will be output.
If you then call it again with 17 bytes of data, then added to the 15
bytes already cached we have a total of 32 bytes. This is a multiple of
16, so 2 blocks (32 bytes) will be output, so:
(inl + cipher_block_size - 1) = (17 + 16 - 1) = 32
Matt
>
> Thank you for your time and help!
>
> Kind regards,
> Wiktor
>
> [1]:
> https://gitlab.com/sequoia-pgp/sequoia/-/merge_requests/1361#note_1150958453
>
More information about the openssl-users
mailing list