Two questions on OpenSSL EVP API

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Two questions on OpenSSL EVP API

Paul Smith
Hi all; I'm working with OpenSSL 1.1.1a, using the EVP interface to
encrypt/decrypt with various ciphers/modes.

I had a couple of questions:


First, the encrypt update docs say:

> the amount of data written may be anything from zero bytes to
> (inl + cipher_block_size - 1)

Is that really true?  For example if my block size is 16 and my input
length is 4, could the encrypt step really write as many as 19 bytes
(4 + 16 - 1)?

I would have thought that the true maximum would be round-up(inl,
cipher_block_size); that is, for inl values 1-15 you'd get 16 bytes,
and for inl values 16-31 you'd get 32 bytes, etc. (I'm not actually
sure whether inl of 16 gets you 16 or 32 bytes...)

Am I wrong about that?  Would some ciphers/modes write beyond the end
of the current "block" and into the next one?


Second, the type of the outl parameter on EVP encrypt update is "int",
rather than (as I would have expected) "unsigned int".  Is there a
possibility that EVP would set &outl to a negative value and if so,
what would that mean?  Do I need to check for this in my code?  Same
with inl; why isn't it "unsigned int"?  Is there ever a reason to pass
in a negative value?

--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: Two questions on OpenSSL EVP API

Dmitry Belyavsky-3
Hello Paul, 

On Wed, Dec 19, 2018 at 6:02 AM Paul Smith <[hidden email]> wrote:
Hi all; I'm working with OpenSSL 1.1.1a, using the EVP interface to
encrypt/decrypt with various ciphers/modes.

I had a couple of questions:


First, the encrypt update docs say:

> the amount of data written may be anything from zero bytes to
> (inl + cipher_block_size - 1)

Is that really true?  For example if my block size is 16 and my input
length is 4, could the encrypt step really write as many as 19 bytes
(4 + 16 - 1)?

I would have thought that the true maximum would be round-up(inl,
cipher_block_size); that is, for inl values 1-15 you'd get 16 bytes,
and for inl values 16-31 you'd get 32 bytes, etc. (I'm not actually
sure whether inl of 16 gets you 16 or 32 bytes...)

Am I wrong about that?  Would some ciphers/modes write beyond the end
of the current "block" and into the next one?

When you use a block cipher and pass data less than block size, it is stored in the internal buffer. 
In this case you do not get encrypted data until there is enough plain text to encrypt the full block.

When you add more data, if you pass enough data to finalize a previously unfinished block, 
you get more long ciphertext than plaintext passed in a particular call of CipherUpdate.
 


Second, the type of the outl parameter on EVP encrypt update is "int",
rather than (as I would have expected) "unsigned int".  Is there a
possibility that EVP would set &outl to a negative value and if so,
what would that mean?  Do I need to check for this in my code?  Same
with inl; why isn't it "unsigned int"?  Is there ever a reason to pass
in a negative value?

I strongly suspect just historical reasons here.
 
--
SY, Dmitry Belyavsky

--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: Two questions on OpenSSL EVP API

Paul Smith
On Wed, 2018-12-19 at 08:57 +0300, Dmitry Belyavsky wrote:

> > I would have thought that the true maximum would be round-up(inl,
> > cipher_block_size); that is, for inl values 1-15 you'd get 16
> > bytes, and for inl values 16-31 you'd get 32 bytes, etc. (I'm not
> > actually sure whether inl of 16 gets you 16 or 32 bytes...)
> >
> > Am I wrong about that?  Would some ciphers/modes write beyond the
> > end of the current "block" and into the next one?
>
> When you use a block cipher and pass data less than block size, it is
> stored in the internal buffer.  In this case you do not get encrypted
> data until there is enough plain text to encrypt the full block.
>
> When you add more data, if you pass enough data to finalize a
> previously unfinished block, you get more long ciphertext than
> plaintext passed in a particular call of CipherUpdate.

I see.  So you potentially need enough for an almost full previous
block, plus the current data.  That makes sense.

Thanks!

--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: Two questions on OpenSSL EVP API

Richard Levitte - VMS Whacker-2
In reply to this post by Paul Smith
In message <[hidden email]> on Tue, 18 Dec 2018 20:54:30 -0500, Paul Smith <[hidden email]> said:

> Hi all; I'm working with OpenSSL 1.1.1a, using the EVP interface to
> encrypt/decrypt with various ciphers/modes.
>
> I had a couple of questions:
>
>
> First, the encrypt update docs say:
>
> > the amount of data written may be anything from zero bytes to
> > (inl + cipher_block_size - 1)
>
> Is that really true?  For example if my block size is 16 and my input
> length is 4, could the encrypt step really write as many as 19 bytes
> (4 + 16 - 1)?
>
> I would have thought that the true maximum would be round-up(inl,
> cipher_block_size); that is, for inl values 1-15 you'd get 16 bytes,
> and for inl values 16-31 you'd get 32 bytes, etc. (I'm not actually
> sure whether inl of 16 gets you 16 or 32 bytes...)
>
> Am I wrong about that?  Would some ciphers/modes write beyond the end
> of the current "block" and into the next one?

Some modes add extra data.  For example, you get an IV block first
when encrypting in CBC mode.

> Second, the type of the outl parameter on EVP encrypt update is "int",
> rather than (as I would have expected) "unsigned int".  Is there a
> possibility that EVP would set &outl to a negative value and if so,
> what would that mean?  Do I need to check for this in my code?  Same
> with inl; why isn't it "unsigned int"?  Is there ever a reason to pass
> in a negative value?

This is most likely an artefact of how the API was originally
written.  Huge portions of the API have remained unchanged for quite a
long time.  If this API was written today, we would likely use size_t.
Changing int to size_t is something I personally would like to do for
some major release ('cause it will only happen in a major release),
but that will also mean that applications using our libraries will
have to change...

You *can* pass in a negative value to EVP_EncryptUpdate, and all that
will happen is...  well, nothing much in the general case:

    if (inl <= 0) {
        *outl = 0;
        return inl == 0;
    }

Cheers,
Richard

--
Richard Levitte         [hidden email]
OpenSSL Project         http://www.openssl.org/~levitte/
--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users