php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #76935 "chacha20-poly1305" is an AEAD but does not work like AEAD
Submitted: 2018-09-26 09:05 UTC Modified: 2018-10-02 17:03 UTC
From: patrakov at gmail dot com Assigned: leigh (profile)
Status: Assigned Package: OpenSSL related
PHP Version: 7.2.10 OS: Linux
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: patrakov at gmail dot com
New email:
PHP Version: OS:

 

 [2018-09-26 09:05 UTC] patrakov at gmail dot com
Description:
------------
"chacha20-poly1305" is listed in the result of openssl_get_cipher_methods(). Wikipedia says it is an AEAD. I.e., if I call openssl_encrypt and provide a reference to a variable that is supposed to get the authentication tag, I expect it to get the tag. Instead, I get this warning:

PHP Warning:  openssl_encrypt(): The authenticated tag cannot be provided for cipher that doesn not support AEAD in /home/aep/aead-test/index.php on line 17

There is a pure PHP implementation of chacha20-poly1305, and it does support the AEAD mode (i.e. gets a tag). It is available as "leigh/aead-chacha20-poly1305" via composer, and the test script below uses it for reference.

Test script:
---------------
<?php

# make sure that you used Composer to get "leigh/aead-chacha20-poly1305"
require __DIR__ . '/vendor/autoload.php';

$key = str_repeat('k', 32);
$nonce = str_repeat('n', 12);

$plaintext = '12345678';
$aad = '';
list($ciphertext, $tag) = \ChaCha20Poly1305\encrypt($key, $nonce, $aad, $plaintext);
$cl = implode(unpack("H*", $ciphertext));
$tl = implode(unpack("H*", $tag));

print("Pure PHP\n");
print("Ciphertext: $cl, tag: $tl\n");

$openssl_ct = openssl_encrypt($plaintext, "chacha20-poly1305", $key, OPENSSL_RAW_DATA, $nonce, $openssl_tag, $aad);
$ocl = implode(unpack("H*", $openssl_ct));
$otl = implode(unpack("H*", $openssl_tag));

print("OpenSSL\n");
print("Ciphertext: $ocl, tag: $otl\n");


Expected result:
----------------
Pure PHP
Ciphertext: bfcd0d66f7e49c21, tag: e48864c53c4deb83bcee96add54ef851
OpenSSL
Ciphertext: bfcd0d66f7e49c21, tag: e48864c53c4deb83bcee96add54ef851


Actual result:
--------------
Pure PHP
Ciphertext: bfcd0d66f7e49c21, tag: e48864c53c4deb83bcee96add54ef851
PHP Warning:  openssl_encrypt(): The authenticated tag cannot be provided for cipher that doesn not support AEAD in /home/aep/aead-test/index.php on line 17
OpenSSL
Ciphertext: bfcd0d66f7e49c21, tag: 


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2018-10-02 16:50 UTC] cmb@php.net
-Assigned To: +Assigned To: leigh
 [2018-10-02 16:50 UTC] cmb@php.net
According to the OpenSSL Wiki only AES with GCM or CCM mode is
currently supported for AEAD[1].  Is that correct, Leigh?  If so,
this would be a doc bug.

[1] <https://wiki.openssl.org/index.php/EVP_Authenticated_Encryption_and_Decryption>
 [2018-10-02 17:03 UTC] requinix@php.net
I was looking at the code last week and it seems there is AEAD support, but it works differently from the GCM and CCM styles: a special AEAD flag to be detected separately.

There is a tag getter and setter to use. I hacked together some support in PHP for it by modifying that one function that sets is_aead and I got a tag back, but it didn't match the expected value, so either it's not fully supported yet or it will take more work than what I did.
 
PHP Copyright © 2001-2019 The PHP Group
All rights reserved.
Last updated: Fri Nov 22 22:01:27 2019 UTC