mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
Implement FR #76935: OpenSSL chacha20-poly1305 AEAD support
This adds support for ChaCha20-Poly1305 AEAD algorithm so it is possible to use it in the same way as AES GCM and other AEAD algorithms. This is available in OpenSSL 1.1.0+.
This commit is contained in:
parent
505e8d2a04
commit
1407968891
4 changed files with 138 additions and 7 deletions
2
NEWS
2
NEWS
|
@ -17,6 +17,8 @@ PHP NEWS
|
|||
- OpenSSL:
|
||||
. Fixed bug GH-9310 (SSL local_cert and local_pk do not respect
|
||||
open_basedir). (Jakub Zelenka)
|
||||
. Implement FR #76935 ("chacha20-poly1305" is an AEAD but does not work like
|
||||
AEAD). (Jakub Zelenka)
|
||||
|
||||
- Random:
|
||||
. Fixed bug GH-9415 (Randomizer::getInt(0, 2**32 - 1) with Mt19937
|
||||
|
|
|
@ -7145,27 +7145,43 @@ struct php_openssl_cipher_mode {
|
|||
int aead_ivlen_flag;
|
||||
};
|
||||
|
||||
static void php_openssl_load_cipher_mode(struct php_openssl_cipher_mode *mode, const EVP_CIPHER *cipher_type) /* {{{ */
|
||||
#if PHP_OPENSSL_API_VERSION >= 0x10100
|
||||
static inline void php_openssl_set_aead_flags(struct php_openssl_cipher_mode *mode) {
|
||||
mode->is_aead = true;
|
||||
mode->aead_get_tag_flag = EVP_CTRL_AEAD_GET_TAG;
|
||||
mode->aead_set_tag_flag = EVP_CTRL_AEAD_SET_TAG;
|
||||
mode->aead_ivlen_flag = EVP_CTRL_AEAD_SET_IVLEN;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void php_openssl_load_cipher_mode(struct php_openssl_cipher_mode *mode, const EVP_CIPHER *cipher_type)
|
||||
{
|
||||
int cipher_mode = EVP_CIPHER_mode(cipher_type);
|
||||
memset(mode, 0, sizeof(struct php_openssl_cipher_mode));
|
||||
switch (cipher_mode) {
|
||||
#ifdef EVP_CIPH_OCB_MODE
|
||||
#if PHP_OPENSSL_API_VERSION >= 0x10100
|
||||
/* Since OpenSSL 1.1, all AEAD ciphers use a common framework. We check for
|
||||
* EVP_CIPH_OCB_MODE, because LibreSSL does not support it. */
|
||||
case EVP_CIPH_GCM_MODE:
|
||||
# ifdef EVP_CIPH_OCB_MODE
|
||||
case EVP_CIPH_OCB_MODE:
|
||||
# endif
|
||||
case EVP_CIPH_CCM_MODE:
|
||||
mode->is_aead = 1;
|
||||
php_openssl_set_aead_flags(mode);
|
||||
/* For OCB mode, explicitly set the tag length even when decrypting,
|
||||
* see https://github.com/openssl/openssl/issues/8331. */
|
||||
mode->set_tag_length_always = cipher_mode == EVP_CIPH_OCB_MODE;
|
||||
mode->set_tag_length_when_encrypting = cipher_mode == EVP_CIPH_CCM_MODE;
|
||||
mode->is_single_run_aead = cipher_mode == EVP_CIPH_CCM_MODE;
|
||||
mode->aead_get_tag_flag = EVP_CTRL_AEAD_GET_TAG;
|
||||
mode->aead_set_tag_flag = EVP_CTRL_AEAD_SET_TAG;
|
||||
mode->aead_ivlen_flag = EVP_CTRL_AEAD_SET_IVLEN;
|
||||
break;
|
||||
# ifdef NID_chacha20_poly1305
|
||||
default:
|
||||
if (EVP_CIPHER_nid(cipher_type) == NID_chacha20_poly1305) {
|
||||
php_openssl_set_aead_flags(mode);
|
||||
}
|
||||
break;
|
||||
|
||||
# endif
|
||||
#else
|
||||
# ifdef EVP_CIPH_GCM_MODE
|
||||
case EVP_CIPH_GCM_MODE:
|
||||
|
@ -7188,7 +7204,6 @@ static void php_openssl_load_cipher_mode(struct php_openssl_cipher_mode *mode, c
|
|||
#endif
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static int php_openssl_validate_iv(const char **piv, size_t *piv_len, size_t iv_required_len,
|
||||
bool *free_iv, EVP_CIPHER_CTX *cipher_ctx, struct php_openssl_cipher_mode *mode) /* {{{ */
|
||||
|
|
|
@ -160,6 +160,72 @@ $php_openssl_cipher_tests = array(
|
|||
'ct' => '1792A4E31E0755FB03E31B22116E6C2DDF9EFD6E33D536F1A0124B0A55BAE884ED93481529C76B6A',
|
||||
),
|
||||
),
|
||||
'chacha20-poly1305' => array(
|
||||
array(
|
||||
'key' => '808182838485868788898a8b8c8d8e8f' .
|
||||
'909192939495969798999a9b9c9d9e9f',
|
||||
'iv' => '070000004041424344454647',
|
||||
'aad' => '50515253c0c1c2c3c4c5c6c7',
|
||||
'tag' => '1ae10b594f09e26a7e902ecbd0600691',
|
||||
'pt' => '4c616469657320616e642047656e746c' .
|
||||
'656d656e206f662074686520636c6173' .
|
||||
'73206f66202739393a20496620492063' .
|
||||
'6f756c64206f6666657220796f75206f' .
|
||||
'6e6c79206f6e652074697020666f7220' .
|
||||
'746865206675747572652c2073756e73' .
|
||||
'637265656e20776f756c642062652069' .
|
||||
'742e',
|
||||
'ct' => 'd31a8d34648e60db7b86afbc53ef7ec2' .
|
||||
'a4aded51296e08fea9e2b5a736ee62d6' .
|
||||
'3dbea45e8ca9671282fafb69da92728b' .
|
||||
'1a71de0a9e060b2905d6a5b67ecd3b36' .
|
||||
'92ddbd7f2d778b8c9803aee328091b58' .
|
||||
'fab324e4fad675945585808b4831d7bc' .
|
||||
'3ff4def08e4b7a9de576d26586cec64b' .
|
||||
'6116',
|
||||
),
|
||||
array(
|
||||
'key' => '1c9240a5eb55d38af333888604f6b5f0' .
|
||||
'473917c1402b80099dca5cbc207075c0',
|
||||
'iv' => '000000000102030405060708',
|
||||
'aad' => 'f33388860000000000004e91',
|
||||
'tag' => 'eead9d67890cbb22392336fea1851f38',
|
||||
'pt' => '496e7465726e65742d44726166747320' .
|
||||
'61726520647261667420646f63756d65' .
|
||||
'6e74732076616c696420666f72206120' .
|
||||
'6d6178696d756d206f6620736978206d' .
|
||||
'6f6e74687320616e64206d6179206265' .
|
||||
'20757064617465642c207265706c6163' .
|
||||
'65642c206f72206f62736f6c65746564' .
|
||||
'206279206f7468657220646f63756d65' .
|
||||
'6e747320617420616e792074696d652e' .
|
||||
'20497420697320696e617070726f7072' .
|
||||
'6961746520746f2075736520496e7465' .
|
||||
'726e65742d4472616674732061732072' .
|
||||
'65666572656e6365206d617465726961' .
|
||||
'6c206f7220746f206369746520746865' .
|
||||
'6d206f74686572207468616e20617320' .
|
||||
'2fe2809c776f726b20696e2070726f67' .
|
||||
'726573732e2fe2809d',
|
||||
'ct' => '64a0861575861af460f062c79be643bd' .
|
||||
'5e805cfd345cf389f108670ac76c8cb2' .
|
||||
'4c6cfc18755d43eea09ee94e382d26b0' .
|
||||
'bdb7b73c321b0100d4f03b7f355894cf' .
|
||||
'332f830e710b97ce98c8a84abd0b9481' .
|
||||
'14ad176e008d33bd60f982b1ff37c855' .
|
||||
'9797a06ef4f0ef61c186324e2b350638' .
|
||||
'3606907b6a7c02b0f9f6157b53c867e4' .
|
||||
'b9166c767b804d46a59b5216cde7a4e9' .
|
||||
'9040c5a40433225ee282a1b0a06c523e' .
|
||||
'af4534d7f83fa1155b0047718cbc546a' .
|
||||
'0d072b04b3564eea1b422273f548271a' .
|
||||
'0bb2316053fa76991955ebd63159434e' .
|
||||
'cebb4e466dae5a1073a6727627097a10' .
|
||||
'49e617d91d361094fa68f0ff77987130' .
|
||||
'305beaba2eda04df997b714d6c6f2c29' .
|
||||
'a6ad5cb4022b02709b',
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
function openssl_get_cipher_tests($method)
|
||||
|
|
48
ext/openssl/tests/openssl_encrypt_chacha20_poly1305.phpt
Normal file
48
ext/openssl/tests/openssl_encrypt_chacha20_poly1305.phpt
Normal file
|
@ -0,0 +1,48 @@
|
|||
--TEST--
|
||||
openssl_encrypt() with ChaCha20 and Poly1305 cipher algorithm tests
|
||||
--EXTENSIONS--
|
||||
openssl
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!in_array('chacha20-poly1305', openssl_get_cipher_methods()))
|
||||
die("skip: chacha20-poly1305 not available");
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once __DIR__ . "/cipher_tests.inc";
|
||||
$method = 'chacha20-poly1305';
|
||||
$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);
|
||||
}
|
||||
|
||||
// Empty IV error
|
||||
var_dump(openssl_encrypt('data', $method, 'password', 0, '', $tag, ''));
|
||||
|
||||
// Failing to retrieve tag (max is 16 bytes)
|
||||
var_dump(openssl_encrypt('data', $method, 'password', 0, str_repeat('x', 12), $tag, '', 20));
|
||||
|
||||
// Failing when no tag supplied
|
||||
var_dump(openssl_encrypt('data', $method, 'password', 0, str_repeat('x', 12)));
|
||||
?>
|
||||
--EXPECTF--
|
||||
TEST 0
|
||||
bool(true)
|
||||
bool(true)
|
||||
TEST 1
|
||||
bool(true)
|
||||
bool(true)
|
||||
|
||||
Warning: openssl_encrypt(): Setting of IV length for AEAD mode failed in %s on line %d
|
||||
bool(false)
|
||||
|
||||
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…
Add table
Add a link
Reference in a new issue