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

 ID:                 60798
 Updated by:         s...@php.net
 Reported by:        ktk at enterprise dot bidmc dot harvard dot edu
 Summary:            Regression: uninitialized memory in
                     openssl_encrypt() with zero-length $data
-Status:             Assigned
+Status:             Feedback
 Type:               Bug
 Package:            OpenSSL related
 Operating System:   Slackware x86_64
 PHP Version:        5.3.9
 Assigned To:        scottmac
 Block user comment: N
 Private report:     N

 New Comment:

Please try using this snapshot:

  http://snaps.php.net/php5.4-latest.tar.gz
 
For Windows:

  http://windows.php.net/snapshots/

Seems to work fine in 5.4.


Previous Comments:
------------------------------------------------------------------------
[2012-01-19 03:08:18] ktk at enterprise dot bidmc dot harvard dot edu

Description:
------------
A regression was introduced in php 5.3.9 to the file ext/openssl/openssl.c 
which causes openssl_encrypt("", "aes-128-cbc", "password") to use 
uninitialized memory when calling the underlying AES_cbc_encrypt() whenever the 
length of the $data argument is zero.  This results in either a corrupted 
return value, or a segmentation fault, depending upon what exists in php's 
memory heap.

I bisected the code difference between php 5.3.8 and 5.3.9 and have attached 
the errant patch to this bug report.

The problem patch introduces the following code, which for reasons unknown 
fails to call the update function whenever the length of the data argument is 
zero:
-       EVP_EncryptUpdate(&cipher_ctx, outbuf, &i, ...);
+       if (data_len > 0) {
+               EVP_EncryptUpdate(&cipher_ctx, outbuf, &i, ...);
+       }

Reverting the attached patch fixes the problem for me.

I'm seeing this problem on both x86_64 (64 bit) and i686 (32 bit) processor 
architectures.  OS is Slackware in both cases, with php linked against openssl 
version 1.0.0g (ditto for openssl 1.0.0e and 1.0.0f), glibc 2.14.1 and compiled 
with gcc 4.5.3.

The corruption/segfault occurs whether or not an initialization vector is 
passed to the function; the only requirement it seems is the zero-length data 
(ergo, the omission of the call to EVP_EncryptUpdate()).

Test script:
---------------
<?php
var_dump(openssl_encrypt("", "aes-128-cbc", "password",
                         false, str_repeat(chr(0), 16)));
$vec = str_repeat(chr(0), 16);
var_dump(openssl_encrypt("", "aes-128-cbc", "password",
                         false, $vec));
var_dump(openssl_encrypt("", "aes-128-cbc", "password"));

unset($vec);
$memory = "Let's use some memory!";
$vec = str_repeat(chr(0), 16);
var_dump(openssl_encrypt("", "aes-128-cbc", "password",
                         false, $vec));
?>

Expected result:
----------------
string(24) "xrQjTh0HCclFET5PKpYH9w=="
string(24) "xrQjTh0HCclFET5PKpYH9w=="

Warning: openssl_encrypt(): Using an empty Initialization Vector (iv) is 
potentially insecure and not recommended in test.php on line 7
string(24) "xrQjTh0HCclFET5PKpYH9w=="
string(24) "xrQjTh0HCclFET5PKpYH9w=="

Actual result:
--------------
GNU gdb (GDB) 7.2
Reading symbols from /usr/bin/php...done.
(gdb) set args test.php
(gdb) run
Starting program: /usr/bin/php test.php
[Thread debugging using libthread_db enabled]
string(24) "AMa0I04dBwnJRRE+TyqWB/c="
string(24) "xrQjTh0HCclFET5PKpYH9w=="

Warning: openssl_encrypt(): Using an empty Initialization Vector (iv) is 
potentially insecure and not recommended in test.php on line 7
string(24) "xrQjTh0HCclFET5PKpYH9w=="

Program received signal SIGSEGV, Segmentation fault.
0xb767cb7c in AES_cbc_encrypt () from /lib/libcrypto.so.1
(gdb) 


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



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

Reply via email to