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