Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ PHP NEWS

- OpenSSL:
. Added AES-SIV support. (jordikroon)
. Added AES-GCM-SIV support. (Rakdos8)
. Implemented GH-20310 (No critical extension indication in
openssl_x509_parse() output). (StephenWall)

Expand Down
3 changes: 3 additions & 0 deletions ext/openssl/openssl_backend_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -1658,6 +1658,9 @@ void php_openssl_load_cipher_mode(struct php_openssl_cipher_mode *mode, const EV
#ifdef EVP_CIPH_SIV_MODE
case EVP_CIPH_SIV_MODE:
#endif
#ifdef EVP_CIPH_GCM_SIV_MODE
case EVP_CIPH_GCM_SIV_MODE:
#endif
#ifdef EVP_CIPH_OCB_MODE
case EVP_CIPH_OCB_MODE:
/* For OCB mode, explicitly set the tag length even when decrypting,
Expand Down
27 changes: 27 additions & 0 deletions ext/openssl/tests/cipher_tests.inc
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,33 @@ $php_openssl_cipher_tests = array(
'21ad626dc866cc539f2d0e34b6824fc3',
),
),
/* RFC 8452 Appendix C.2 vectors for AES-256-GCM-SIV. */
'aes-256-gcm-siv' => array(
array(
'key' => '0100000000000000000000000000000000000000000000000000000000000000',
'iv' => '030000000000000000000000',
'aad' => '',
'tag' => '07f5f4169bbf55a8400cd47ea6fd400f',
'pt' => '',
'ct' => '',
),
array(
'key' => '0100000000000000000000000000000000000000000000000000000000000000',
'iv' => '030000000000000000000000',
'aad' => '',
'tag' => '843122130f7364b761e0b97427e3df28',
'pt' => '0100000000000000',
'ct' => 'c2ef328e5c71c83b',
),
array(
'key' => '0100000000000000000000000000000000000000000000000000000000000000',
'iv' => '030000000000000000000000',
'aad' => '01',
'tag' => '91213f267e3b452f02d01ae33e4ec854',
'pt' => '0200000000000000',
'ct' => '1de22967237a8132',
),
),
'chacha20-poly1305' => array(
array(
'key' => '808182838485868788898a8b8c8d8e8f' .
Expand Down
61 changes: 61 additions & 0 deletions ext/openssl/tests/openssl_decrypt_gcm_siv.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
--TEST--
openssl_decrypt() with GCM-SIV cipher algorithm tests
--EXTENSIONS--
openssl
--SKIPIF--
<?php
if (!in_array('aes-256-gcm-siv', openssl_get_cipher_methods())) {
die("skip aes-256-gcm-siv not available (requires OpenSSL >= 3.2)");
}
?>
--FILE--
<?php
require_once __DIR__ . "/cipher_tests.inc";
$method = 'aes-256-gcm-siv';
$tests = openssl_get_cipher_tests($method);

foreach ($tests as $idx => $test) {
echo "TEST $idx\n";
$pt = openssl_decrypt($test['ct'], $method, $test['key'], OPENSSL_RAW_DATA,
$test['iv'], $test['tag'], $test['aad']);
var_dump($test['pt'] === $pt);
}

// Use the last vector (non-empty pt + AAD) for tampering checks.
echo "TEST WRONGTAG\n";
$bad_tag = $test['tag'];
$bad_tag[0] = chr(ord($bad_tag[0]) ^ 0x01);
var_dump(openssl_decrypt($test['ct'], $method, $test['key'], OPENSSL_RAW_DATA,
$test['iv'], $bad_tag, $test['aad']));

echo "TEST WRONGCT\n";
$bad_ct = $test['ct'];
$bad_ct[0] = chr(ord($bad_ct[0]) ^ 0x01);
var_dump(openssl_decrypt($bad_ct, $method, $test['key'], OPENSSL_RAW_DATA,
$test['iv'], $test['tag'], $test['aad']));

echo "TEST WRONGNONCE\n";
$bad_iv = $test['iv'];
$bad_iv[0] = chr(ord($bad_iv[0]) ^ 0x01);
var_dump(openssl_decrypt($test['ct'], $method, $test['key'], OPENSSL_RAW_DATA,
$bad_iv, $test['tag'], $test['aad']));

echo "TEST WRONGAAD\n";
var_dump(openssl_decrypt($test['ct'], $method, $test['key'], OPENSSL_RAW_DATA,
$test['iv'], $test['tag'], 'unexpected aad'));
?>
--EXPECT--
TEST 0
bool(true)
TEST 1
bool(true)
TEST 2
bool(true)
TEST WRONGTAG
bool(false)
TEST WRONGCT
bool(false)
TEST WRONGNONCE
bool(false)
TEST WRONGAAD
bool(false)
46 changes: 46 additions & 0 deletions ext/openssl/tests/openssl_encrypt_gcm_siv.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
--TEST--
openssl_encrypt() with GCM-SIV cipher algorithm tests
--EXTENSIONS--
openssl
--SKIPIF--
<?php
if (!in_array('aes-256-gcm-siv', openssl_get_cipher_methods())) {
die("skip aes-256-gcm-siv not available (requires OpenSSL >= 3.2)");
}
?>
--FILE--
<?php
require_once __DIR__ . "/cipher_tests.inc";
$method = 'aes-256-gcm-siv';
$tests = openssl_get_cipher_tests($method);

foreach ($tests as $idx => $test) {
echo "TEST $idx\n";
$ct = openssl_encrypt($test['pt'], $method, $test['key'], OPENSSL_RAW_DATA,
$test['iv'], $tag, $test['aad'], strlen($test['tag']));
var_dump($test['ct'] === $ct);
var_dump($test['tag'] === $tag);
}

// Failing to retrieve tag (max is 16 bytes)
var_dump(openssl_encrypt('data', $method, str_repeat('x', 32), 0, str_repeat('x', 12), $tag, '', 20));

// Failing when no tag supplied
var_dump(openssl_encrypt('data', $method, str_repeat('x', 32), 0, str_repeat('x', 12)));
?>
--EXPECTF--
TEST 0
bool(true)
bool(true)
TEST 1
bool(true)
bool(true)
TEST 2
bool(true)
bool(true)

Warning: openssl_encrypt(): Retrieving verification tag failed in %s on line %d
bool(false)

Warning: openssl_encrypt(): A tag should be provided when using AEAD mode in %s on line %d
bool(false)
Loading