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.
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=67304Further 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.
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.
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.
Hey
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.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.--
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
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.
length (not sure how of
Not sure how often tag lengths aside from 16 are used.
length (not sure how of
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.
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.
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
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.
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.
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.
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 ;)