# OpenSSL ext. improvements for authenticated cipher modes.

- Thread: https://externals.io/message/81489
- Original archive: https://news-web.php.net/php.internals/81489
- Started by Leigh on 2015-01-31T15:53:02+00:00
- Messages: 9
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #81489 — Leigh — 2015-01-31T15:53:02+00:00

URL: https://externals.io/message/81489#81489

Hi list,

A couple of bug reports have highlighted the fact that our
openssl_encrypt and openssl_decrupt functions have no way of getting
or setting tags required for authenticated cipher modes (i.e. GCM,
CCM, OCB (not sure if this is available in OpenSSL)).

https://bugs.php.net/bug.php?id=68962
https://bugs.php.net/bug.php?id=67304

Further to this, we have no way of setting any associated data.

I think we absolutely must provide a method for users to be able to
use authenticated encryption, and would like some opinions on how much
flexibility we give users, and the best method for exposing this
functionality.

At the very basic end of the spectrum, we could have openssl_get_tag
and openssl_set_tag, or add an extra parameter to the end of
openssl_encrypt and openssl_decrypt (pass by ref for encrypt, like
preg $matches) this would cover the majority of use cases.

However I absolutely think that the associated data also needs to be
supported, and possibly the ability to change the tag length.

At this point we're starting to get into the territory where an
$options array is needed, or we add a lot of parameters to the end of
functions. I don't really think it's good to add up to 3 more params
to these functions.

What do you guys and girls think is the best way of tackling this?

Cheers,

Leigh.

---

## #81490 — Jason Gerfen — 2015-01-31T16:13:52+00:00

URL: https://externals.io/message/81489#81490 · In reply to: #81489

> Hi list,
>
> A couple of bug reports have highlighted the fact that our
> openssl_encrypt and openssl_decrupt functions have no way of getting
> or setting tags required for authenticated cipher modes (i.e. GCM,
> CCM, OCB (not sure if this is available in OpenSSL)).
>
> https://bugs.php.net/bug.php?id=68962
> https://bugs.php.net/bug.php?id=67304
>
> Further to this, we have no way of setting any associated data.
>
> I think we absolutely must provide a method for users to be able to
> use authenticated encryption, and would like some opinions on how much
> flexibility we give users, and the best method for exposing this
> functionality.
>
> At the very basic end of the spectrum, we could have openssl_get_tag
> and openssl_set_tag, or add an extra parameter to the end of
> openssl_encrypt and openssl_decrypt (pass by ref for encrypt, like
> preg $matches) this would cover the majority of use cases.
>
>
​I think exposing this to the user will only cause confusion and allow
users to implement mistakes to the algorithm and mode usage.​



> However I absolutely think that the associated data also needs to be
> supported, and possibly the ability to change the tag length.
>
> At this point we're starting to get into the territory where an
> $options array is needed, or we add a lot of parameters to the end of
> functions. I don't really think it's good to add up to 3 more params
> to these functions.
>
> What do you guys and girls think is the best way of tackling this?
>
> Cheers,
>
> Leigh.
>
> --
> 
> 
>
>
According to the OpenSSL documentation regarding encryption/decryption
using CCM, GCM & OCB modes for authenticated usage would require the
additions of the following constants:

EVP_CTRL_OCB_SET_TAGLEN
EVP_CTRL_SET_IVLEN
EVP_CTRL_GET_TAG
EVP_CTRL_CCM_SET_L
EVP_CTRL_CCM_SET_IVLEN
EVP_aes_256_gcm()
EVP_aes_128_gcm()
​

​That coupled with the use of the ​

EVP_CIPHER_CTX_ctrl()

​should provide the needed functionality ​as described in
http://wiki.openssl.org/index.php/EVP_Authenticated_Encryption_and_Decryption
the documentation for using the EVP authenticated modes for
encryption/decryption.

---

## #81491 — Leigh — 2015-01-31T16:21:29+00:00

URL: https://externals.io/message/81489#81491 · In reply to: #81490

> 
> > […]
>
> I think exposing this to the user will only cause confusion and allow users
> to implement mistakes to the algorithm and mode usage.
>

set/get tag functions are alto my least favourite options.

>
> According to the OpenSSL documentation regarding encryption/decryption using
> CCM, GCM & OCB modes for authenticated usage would require the additions of
> the following constants:
>
> EVP_CTRL_OCB_SET_TAGLEN
> EVP_CTRL_SET_IVLEN
> EVP_CTRL_GET_TAG
> EVP_CTRL_CCM_SET_L
> EVP_CTRL_CCM_SET_IVLEN
> EVP_aes_256_gcm()
> EVP_aes_128_gcm()
>
> That coupled with the use of the
>
> EVP_CIPHER_CTX_ctrl()
>
> should provide the needed functionality as described in
> http://wiki.openssl.org/index.php/EVP_Authenticated_Encryption_and_Decryption
> the documentation for using the EVP authenticated modes for
> encryption/decryption.
>

Thanks, I have done some cursory research into how it should be
implemented, but I wanted this discussion to be about how we should
present the functionality to the user. Implementation details can come
second once we have a consensus on what is/isn't too much, and what
method we should use to allow this functionality to be used.

---

## #81536 — Jakub Zelenka — 2015-02-01T17:57:04+00:00

URL: https://externals.io/message/81489#81536 · In reply to: #81491

Hey



> 
> > […]
> users
> > […]
>
> set/get tag functions are alto my least favourite options.
>
> > […]
> using
> > […]
> of
> > […]
> http://wiki.openssl.org/index.php/EVP_Authenticated_Encryption_and_Decryption
> > […]
>
> Thanks, I have done some cursory research into how it should be
> implemented, but I wanted this discussion to be about how we should
> present the functionality to the user. Implementation details can come
> second once we have a consensus on what is/isn't too much, and what
> method we should use to allow this functionality to be used.
>
> --
> 
> 
>
>

Hey,

I have already implemented all of this in crypto ext (
https://github.com/bukka/php-crypto ) and also added support for streams
(e.g.
https://github.com/bukka/php-crypto/blob/master/tests/stream_filters_cipher_gcm_dec_read.phpt
)
and objective context. However crypto is and probably quite some time will
be in the dev stability. I have put that work on hold for some time (due to
php 7 api changes) but plan to resume it soon.

Anyway this is a bit different as it is a bit more complex and bit too much
for openssl ext. The thing is that the symmetric cypto functions are just
openssl_encrypt and openssl_decrypt and they don't have any context. I'm
not sure how the proposed openssl_*et_tag would work without context. The
options array makes definitely more sense to me. It's basically what I used
for stream context ( some doc can be found here:
https://github.com/bukka/php-crypto/issues/8 ). The only problem is how to
get the resulted tag. I used stream meta array for that in crypto streams.
If we don't want to break BC, then we would probably need another ref param
openssl_encrypt. Something like:

string openssl_encrypt ( string $data , string $method , string $password
[, mixed $options = `NULL` [, string $iv = "" [, string &$tag = `NULL` ] ] ] )

The options would be overloaded for BC (if it's int, then the same as
before or you can use array for further options as AAD...).

What's you thoughts?

Btw. I think I could do or help with the implementation if there is an
interest in that feature in PHP 7 . It would be sort of port from crypto
where I also have bunch of test for that (supported are just ccm and gcm).

Cheers

---

## #81581 — Leigh — 2015-02-02T10:57:24+00:00

URL: https://externals.io/message/81489#81581 · In reply to: #81536

> Hey,
>
> I have already implemented all of this in crypto ext (
> https://github.com/bukka/php-crypto ) and also added support for streams
> (e.g.
> https://github.com/bukka/php-crypto/blob/master/tests/stream_filters_cipher_gcm_dec_read.phpt
> ) and objective context. However crypto is and probably quite some time will
> be in the dev stability. I have put that work on hold for some time (due to
> php 7 api changes) but plan to resume it soon.

I hadn't seen this before. Has it been discussed somewhere and I
missed it? Watching the repo for now, hopefully I can find some time
to look over it and contribute.

> Anyway this is a bit different as it is a bit more complex and bit too much
> for openssl ext. The thing is that the symmetric cypto functions are just
> openssl_encrypt and openssl_decrypt and they don't have any context. I'm not
> sure how the proposed openssl_*et_tag would work without context. The

They would work by dirty hacks :) Like Daniel said, introducing state
is not a preferred option.

> string openssl_encrypt ( string $data , string $method , string $password [,
> mixed $options = `NULL` [, string $iv = "" [, string &$tag = `NULL` ] ] ] )
>
> The options would be overloaded for BC (if it's int, then the same as before
> or you can use array for further options as AAD...).
>
> What's you thoughts?

This is what I originally imagined doing. But the options array isn't
necessary if we say that we don't want the user to control the tag
length (not sure how of

> Btw. I think I could do or help with the implementation if there is an
> interest in that feature in PHP 7 . It would be sort of port from crypto
> where I also have bunch of test for that (supported are just ccm and gcm).

I'm happy doing the implementation but review and critique always welcome.

---

## #81582 — Leigh — 2015-02-02T10:58:57+00:00

URL: https://externals.io/message/81489#81582 · In reply to: #81581

> length (not sure how of

Not sure how often tag lengths aside from 16 are used.

---

## #81583 — Jason Gerfen — 2015-02-02T11:46:38+00:00

URL: https://externals.io/message/81489#81583 · In reply to: #81582

> 
> > […]
>
> Not sure how often tag lengths aside from 16 are used.
>

​
According to documentation provided about the OCB mode of AES it says the
following:

Section 3: The scheme

> The tag length is an integer τ ∈ [0 .. n]. ... As for the tag length, a
> suggested default of τ = 64 is reasonable. Tags of 32 bits are standard in
> retail banking. Tags of 96 bits are used in IPSec. Using a tag of more than
> 80 bits adds questionable security benefit, though it does lengthen each
> cipher text.
>

http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/ocb/ocb-spec.pdf

Maybe `E_WARNING` on any tag length less than 64 would also be useful in OCB
mode(s).

The GCM mode is somewhat different regarding the allowed tag length(s).

Section 5.2.1.2 Output Data

> The bit length of the tag, denoted t, is a security parameter, as
> discussed in Appendix B. In general, t may be any one of the following five
> values: 128, 120, 112, 104, or 96. For certain applications, t may  be 64
> or 32; guidance for the use of these two tag lengths, including
> requirements on the length of the input data and the lifetime of the key in
> these cases, is given in Appendix C.
>

http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf

Tag lengths of 32 & 96 are common in lower level desktop based applications
as noted for IPSec & retail banking applications. I am not sure how common
these smaller tag lengths would apply to PHP, however, given the age of the
bug report compared to the age of the mode(s) requesting use of these
mode(s) doesn't seem to be common.
​

---

## #81584 — Leigh — 2015-02-02T12:03:47+00:00

URL: https://externals.io/message/81489#81584 · In reply to: #81583

> According to documentation provided about the OCB mode of AES it says the
> following:
>
> Section 3: The scheme
> > […]

In Rogaway's own OCB FAQ it states:

The number τ, the tag length of the scheme, is, like the blockcipher
E, a parameter of the mode. It’s a number 0 ≤ τ ≤ 128.

http://web.cs.ucdavis.edu/~rogaway/ocb/ocb-faq.htm

> The GCM mode is somewhat different regarding the allowed tag length(s).
>
> Section 5.2.1.2 Output Data
> > […]

So in both of these cases the largest tag size is 128 bits
(corresponds to the length of 16 that I mentioned - bits -> bytes). A
tag length of 16 is a safe assumption if we don't want to allow the
user to specify, however it could prevent interop with other
applications, if they require a tag of a different length.

---

## #81594 — Jakub Zelenka — 2015-02-02T16:09:50+00:00

URL: https://externals.io/message/81489#81594 · In reply to: #81584

>
> In Rogaway's own OCB FAQ it states:
>
> The number τ, the tag length of the scheme, is, like the blockcipher
> E, a parameter of the mode. It’s a number 0 ≤ τ ≤ 128.
>
> http://web.cs.ucdavis.edu/~rogaway/ocb/ocb-faq.htm
>

The OCB is just in openssl master and won't be released for quite a some
time (scheduled for 1.1.0) so think that you don't have to worry about that
now ;)
