[RFC] [PHP 7.1] libsodium

php.internals

Scott Arciszewski

11 years ago
Hi Internals Team, I'm sure everyone is really focused (and excited) for PHP 7.0.0 later this year, and many of you might not want to discuss what 7.1.x looks like yet. The current state of cryptography in PHP is, well, abysmal. Our two main choices for handling symmetric cryptography are libmcrypt (collecting dust since 2007) and openssl, which lacks a streaming API (e.g. mcrypt_generic) and GCM support. While mcrypt is slowly decomposing in the corner and code is being desperately migrated towards openssl in case a critical vulnerability is discovered in the abandonware choice, the libsodium extension has been growing steadily. Thanks to Remi, it should soon be compatible with both PHP 5.x and 7.x (decided at compile-time). The libsodium library itself has landed in Debian 8 and Ubuntu 15.04 and adoption is expected to persist by the next Ubuntu LTS is released. I think now is a good time to talk about the possibility of making libsodium a core PHP extension, depending on where things are when we near the 7.1 feature freeze. I've just opened an RFC for precisely this purpose: https://wiki.php.net/rfc/libsodium Regards, Scott Arciszewski Chief Development Officer Paragon Initiative Enterprises <https://paragonie.com>

Markus Fischer

11 years ago
On 21.05.2015 03:15, Scott Arciszewski wrote:
> I've just opened an RFC for precisely this purpose: > https://wiki.php.net/rfc/libsodium
From https://github.com/jedisct1/libsodium-php : // Binary to hexadecimal $hex = Sodium::sodium_bin2hex($bin); // Hexadecimal to binary $bin = Sodium::sodium_hex2bin($hex); // Hexadecimal to binary, ignoring a set of characters $bin = Sodium::sodium_hex2bin($hex, $string_of_characters_to_ignore); What's the reason for this redundancy (Sodium::sodium_*) ? thanks, - Markus

Yasuo Ohgaki

11 years ago
Hi Scott, On Thu, May 21, 2015 at 10:15 AM, Scott Arciszewski <scott@paragonie.com> wrote:
> Hi Internals Team, > > I'm sure everyone is really focused (and excited) for PHP 7.0.0 later this > year, and many of you might not want to discuss what 7.1.x looks like yet. > > The current state of cryptography in PHP is, well, abysmal. Our two main > choices for handling symmetric cryptography are libmcrypt (collecting dust > since 2007) and openssl, which lacks a streaming API (e.g. mcrypt_generic) > and GCM support. > > While mcrypt is slowly decomposing in the corner and code is being > desperately migrated towards openssl in case a critical vulnerability is > discovered in the abandonware choice, the libsodium extension has been > growing steadily. Thanks to Remi, it should soon be compatible with both > PHP 5.x and 7.x (decided at compile-time). The libsodium library itself has > landed in Debian 8 and Ubuntu 15.04 and adoption is expected to persist by > the next Ubuntu LTS is released. > > I think now is a good time to talk about the possibility of making > libsodium a core PHP extension, depending on where things are when we near > the 7.1 feature freeze. > > I've just opened an RFC for precisely this purpose: > https://wiki.php.net/rfc/libsodium >
These are examples from github $nonce = Sodium::randombytes_buf(Sodium::CRYPTO_SECRETBOX_NONCEBYTES); $key = [a binary string that must be CRYPTO_SECRETBOX_KEYBYTES long]; $ciphertext = Sodium::crypto_secretbox('test', $nonce, $key); $plaintext = Sodium::crypto_secretbox_open($ciphertext, $nonce, $key); We have coding standard. https://github.com/php/php-src/blob/master/CODING_STANDARDS 6. Method names follow the 'studlyCaps' (also referred to as 'bumpy case' or 'camel caps') naming convention, with care taken to minimize the letter count. The initial letter of the name is lowercase, and each letter that starts a new 'word' is capitalized:: Good: 'connect()' 'getData()' 'buildSomeWidget()' Bad: 'get_Data()' 'buildsomewidget' 'getI()' To include as a core extension, you need standard method names. Keeping old names as alias is fine for me, but main names should be standard names. Regards,
-- Yasuo Ohgaki yohgaki@ohgaki.net

Scott Arciszewski

11 years ago
How should we reconcile your standard recommendations with NaCl proper and how libsodium is used in other languages? I'll try to loop Frank Denis in on this conversation again, but any specific objections (esp. bikeshedding) would probably be best moved towards new issues on the jedisct1/libsodium GitHub repository. On May 25, 2015 2:10 AM, "Yasuo Ohgaki" <yohgaki@ohgaki.net> wrote:

Yasuo Ohgaki

11 years ago
Hi Scott, On Mon, May 25, 2015 at 6:42 PM, Scott Arciszewski <scott@paragonie.com> wrote:
> How should we reconcile your standard recommendations with NaCl proper and > how libsodium is used in other languages? > > I'll try to loop Frank Denis in on this conversation again, but any > specific objections (esp. bikeshedding) would probably be best moved > towards new issues on the jedisct1/libsodium GitHub repository. >
If you look into PHP core modules, you'll notice that almost all functions/methods/classes that are recently added have standard names. I'm aware of there are exceptions, like old names before standards, named wrongly by mistake. These are exceptions. Unless we honor the standard, we'll never achieve naming consistency. PHP module should have its own names if function/method names underlying library does not match the standard. You may name them whatever you think appropriate. Getting rid of "_" might be good enough for most methods. Regards,
-- Yasuo Ohgaki yohgaki@ohgaki.net

Anthony Ferrara

11 years ago
Scott, On Wed, May 20, 2015 at 9:15 PM, Scott Arciszewski <scott@paragonie.com> wrote:
> Hi Internals Team, > > I'm sure everyone is really focused (and excited) for PHP 7.0.0 later this > year, and many of you might not want to discuss what 7.1.x looks like yet. > > The current state of cryptography in PHP is, well, abysmal. Our two main > choices for handling symmetric cryptography are libmcrypt (collecting dust > since 2007) and openssl, which lacks a streaming API (e.g. mcrypt_generic) > and GCM support. > > While mcrypt is slowly decomposing in the corner and code is being > desperately migrated towards openssl in case a critical vulnerability is > discovered in the abandonware choice, the libsodium extension has been > growing steadily. Thanks to Remi, it should soon be compatible with both > PHP 5.x and 7.x (decided at compile-time). The libsodium library itself has > landed in Debian 8 and Ubuntu 15.04 and adoption is expected to persist by > the next Ubuntu LTS is released. > > I think now is a good time to talk about the possibility of making > libsodium a core PHP extension, depending on where things are when we near > the 7.1 feature freeze. > > I've just opened an RFC for precisely this purpose: > https://wiki.php.net/rfc/libsodium
While I definitely do like libsodium and consider it a step in the right direction, I am hesitant overall. The main reason is precisely what happened with mcrypt. In that a library goes unmaintained, and all of a sudden we're stuck using unsupported crypto. I wonder if a PDO-style approach would be better. Where we can have multiple pluggable backends, and provide backend-specific functionality if needed. Targetting a high-level API, not exposing primitives. Something like: $enc = new SymmetricEncryption(":cipher=aes128;hash=sha256"); // Use any available backend which can do aes128+sha256 mac var_dump($enc->encrypt("plaintext", $key)); $enc = new SymmetricEncryption("openssl:cipher=arc4;mode=ctr"); // Use any available backend which can do aes128+sha256 mac var_dump($enc->encrypt("plaintext", $key)); The concept would be that while parts of the algorithm are controllable by the end-user (like cipher choice, possibly mode, etc), we would attempt to prevent insecure usages (no ECB). If you have a need for custom encryption (web service uses a custom format), then use primitives yourself (like openssl/mcrypt/etc). My one issue with libsodium is that if you need NIST compliance, it does nothing for you (considering it uses XSalsa20+ Poly1305). While this is an advantage for some, it's a disadvantage for many. Ideally, I'd like to see a prototype of this library built in PHP that we can play with prior to making into a PECL extension (and ultimately proposed for core). I'd just rather try to get this right, rather than yet another maybe-good-enough-for-now solution. Anthony

Scott Arciszewski

11 years ago
That's fair, and one of the reasons I wanted to make ext/libsodium part of the core was so that segueing into a PDO-style cryptography API would be more natural. Instead of "wrap openssl and maybe wrap libsodium if it's already installed" it would be "wrap what the language already has". Am I mistaken in believing this would be the way forward? Scott Arciszewski Chief Development Officer Paragon Initiative Enterprises <https://paragonie.com> On Tue, May 26, 2015 at 6:47 PM, Anthony Ferrara <ircmaxell@gmail.com> wrote:

Rowan Collins

11 years ago
On 26/05/2015 23:52, Scott Arciszewski wrote:
> That's fair, and one of the reasons I wanted to make ext/libsodium part of > the core was so that segueing into a PDO-style cryptography API would be > more natural. Instead of "wrap openssl and maybe wrap libsodium if it's > already installed" it would be "wrap what the language already has". > > Am I mistaken in believing this would be the way forward?
Well, it doesn't quite match how PDO works, as I understand it - ext/pdo_pgsql isn't implemented on top of ext/pgsql, the two are separate extensions built on top of the libPQ library which Postgres provides. The "PHP Crypto Objects" equivalent would be "wrap openssl in ext/pco_openssl, wrap libsodium in ext/pco_sodium". The dependency management would be no different between ext/openssl and ext/pco_openssl - PHP doesn't *provide* OpenSSL or mcrypt, it *optionally* depends on them, and the same would be true of libsodium, whatever the bindings looked like. As such, bundling an extension which directly exposes libsodium's functions isn't really a pre-requisite for a pluggable architecture, and could harm the effort by being "too good" and allowing the short-term "good enough" solution that Anthony is afraid of. Regards,
-- Rowan Collins [IMSoP]

Francois Poirotte

11 years ago
Hi, I like Anthony's idea of a crypto framework (abstracting away whatever underlying library is actually used). Not sure yet how this could be implemented though. For what it's worth, I started playing with libtomcrypt (yet another crypto API) a few weeks ago as an attempt to replace the old mcrypt extension for my own needs. I found it quite easy to work with, plus the license is very permissive (WTFPL). The result can be seen at https://github.com/fpoirotte/tomcrypt. This is basically a thin wrapper around libtomcrypt's API. The code still has many issues I need to resolve (lack of unit tests, parameter parsing using improper types, not ready for PHP 7 yet, etc.) but I found it to be pretty usable already. Would there be any wider interest for such an extension? Regards, François On 05/27/2015 01:44 AM, Rowan Collins wrote: