Bug #81502 [Fbk->Opn]: $tag argument of openssl_decrypt() should accept null/empty string

From: Date: Fri, 08 Oct 2021 05:28:34 +0000
Subject: Bug #81502 [Fbk->Opn]: $tag argument of openssl_decrypt() should accept null/empty string
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-237094@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=81502&edit=1

 ID:                 81502
 User updated by:    alec at alec dot pl
 Reported by:        alec at alec dot pl
-Summary:            Problem with $tag argument of openssl_decrypt()
+Summary:            $tag argument of openssl_decrypt() should accept
                     null/empty string
-Status:             Feedback
+Status:             Open
 Type:               Bug
 Package:            OpenSSL related
 PHP Version:        8.1.0RC3
 Block user comment: N
 Private report:     N

 New Comment:

Summary updated


Previous Comments:
------------------------------------------------------------------------
[2021-10-07 06:29:57] alec at alec dot pl

Again, to make it clear. I want openssl_decrypt() to support null or empty string in $tag argument
(as not existing) for non-AEAD ciphers.

My real code is here: https://github.com/roundcube/roundcubemail/blob/318d6d08597bbfe481e01bf989150faa8c0403e5/program/lib/Roundcube/rcube.php#L894

With php8.0 I can have ($tag is null):

openssl_decrypt($cipher, $method, $ckey, OPENSSL_RAW_DATA, $iv, $tag);

with php8.1 it throws a deprecation warning, I cannot use this:

openssl_decrypt($cipher, $method, $ckey, OPENSSL_RAW_DATA, $iv, (string) $tag);

because it throws the other warning. I have to use:

if ($tag === null) {
    openssl_decrypt($cipher, $method, $ckey, OPENSSL_RAW_DATA, $iv);
} else {
    openssl_decrypt($cipher, $method, $ckey, OPENSSL_RAW_DATA, $iv, $tag);
}

which I don't like.

------------------------------------------------------------------------
[2021-10-05 17:08:21] alec at alec dot pl

```
<?php
ini_set('error_reporting', E_ALL);
ini_set('display_errors', 'on');

function encrypt($clear)
{
    $key    = 'key';
    $ckey   = '123456789012345678901234';
    $method = 'DES-EDE3-CBC';
    $opts   = OPENSSL_RAW_DATA;
    $iv     = random_bytes(openssl_cipher_iv_length($method));

    $cipher = openssl_encrypt($clear, $method, $ckey, $opts, $iv, $tag);

    $cipher = $iv . $cipher;

    return $cipher;
}

function decrypt($cipher)
{
    $key     = 'key';
    $ckey    = '123456789012345678901234';
    $method  = 'DES-EDE3-CBC';
    $opts    = OPENSSL_RAW_DATA;
    $iv_size = openssl_cipher_iv_length($method);
    $tag     = null;
    
    $iv     = substr($cipher, 0, $iv_size);
    $cipher = substr($cipher, $iv_size);

    return openssl_decrypt($cipher, $method, $ckey, $opts, $iv, $tag);
}

echo decrypt(encrypt('test')) === 'test';
```

One correction, I'm using PHP 8.1.0RC2 on Ubuntu 18.04.

------------------------------------------------------------------------
[2021-10-05 15:17:30] nikic@php.net

I can't reproduce this. Empty tag for non-AEAD cipher does not produce a warning for me and
also matches my reading of the code (see https://github.com/php/php-src/blob/f313854c98e79fa5f4ec5ef9bf8755a15290b1a5/ext/openssl/openssl.c#L7333).

Can you please provide a complete reproducer that demonstrates the issue?

------------------------------------------------------------------------
[2021-10-04 17:12:50] alec at alec dot pl

Description:
------------
If I do:

$tag = null;
openssl_decrypt($cipher, $method, $ckey, $opts, $iv, $tag);

I get:

PHP Deprecated:  openssl_decrypt(): Passing null to parameter #6 ($tag) of type string is
deprecated.

But if I do:

$tag = '';
openssl_decrypt($cipher, $method, $ckey, $opts, $iv, $tag);

I get:

PHP Warning:  openssl_decrypt(): The tag cannot be used because the cipher algorithm does not
support AEAD.

I understand the warnings, but this is not convenient if my code is supposed to support AEAD and
non-AEAD cipher methods. Do I have to do two code paths depending on the cipher method is used?

What's more. The default value for the $tag argument in openssl_encrypt() is null, which sounds
kind of inconsistent.



------------------------------------------------------------------------



--
Edit this bug report at https://bugs.php.net/bug.php?id=81502&edit=1


Thread (9 messages)

« previous php.bugs (#237094) next »